Cách sử dụng một biến môi trường bên trong một chuỗi được trích dẫn trong Bash


91

Tôi đã thử nhiều dạng sau trong một tập lệnh bash:

#!/bin/bash
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

Nhưng tôi không thể lấy cú pháp để mở rộng chính xác COLUMNSbiến môi trường.

Tôi đã thử nhiều dạng sau:

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W $COLUMNS'

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W ${COLUMNS}'

eval svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

Gợi ý?


vậy những ví dụ đó tạo ra điều gì trong trường hợp của bạn? Và bạn muốn họ sản xuất những gì?

lệnh bên ngoài script đang hoạt động?
dfa

Bạn đã thửsvn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W ""$COLUMNS"
Qian Chen

BTW, sử dụng không $@được trích dẫn làm cho nó giống hệt như $*- nghĩa là nó chia "foo bar"thành hai đối số riêng biệt, foobar. Nếu bạn muốn duy trì danh sách đối số ban đầu giống như nó đã được cung cấp cho bạn, bạn muốn "$@".
Charles Duffy

Câu trả lời:


16

Nếu không chắc chắn, bạn có thể sử dụng yêu cầu 'cols' trên terminal và quên COLUMNS:

COLS=$(tput cols)

Vì bất cứ lý do gì, đây là giải pháp duy nhất mà tôi có thể bắt đầu làm việc với trang này (kể từ ngày 11 tháng 5 10:38 ET). Cảm ơn
Jamie

397

Chỉ là một ghi chú / tóm tắt nhanh cho bất kỳ ai đã đến đây qua Google để tìm kiếm câu trả lời cho câu hỏi chung được hỏi trong tiêu đề (như tôi đã từng). Bất kỳ điều nào sau đây sẽ hoạt động để có quyền truy cập vào các biến shell bên trong dấu ngoặc kép:

echo "$VARIABLE"
echo "${VARIABLE}"

Sử dụng các dấu ngoặc kép là vấn đề chính. Theo Sổ tay Tham khảo Bash :

Việc đặt các ký tự trong dấu ngoặc kép ( ') giữ nguyên giá trị chữ của mỗi ký tự trong dấu ngoặc kép. Một dấu ngoặc kép có thể không xảy ra giữa các dấu nháy đơn, ngay cả khi đứng trước dấu gạch chéo ngược. [...] Kèm theo ký tự trong dấu ngoặc kép ( ") giữ gìn giá trị văn chương của tất cả các ký tự trong dấu ngoặc kép, với ngoại lệ của $, `, \, và, khi mở rộng lịch sử được kích hoạt, !. Các ký tự $và `giữ lại ý nghĩa đặc biệt của chúng trong dấu ngoặc kép (xem Phần mở rộng của Shell). Các dấu chéo ngược vẫn giữ được ý nghĩa đặc biệt của nó chỉ khi theo sau là một trong những nhân vật sau: $, `, ",\, hoặc dòng mới. Trong dấu ngoặc kép, dấu gạch chéo ngược đứng sau một trong các ký tự này sẽ bị loại bỏ. Dấu gạch chéo ngược đứng trước các ký tự không có nghĩa đặc biệt không được sửa đổi. Một dấu ngoặc kép có thể được trích dẫn trong dấu ngoặc kép bằng cách đặt trước nó bằng dấu gạch chéo ngược. Nếu được bật, mở rộng lịch sử sẽ được thực hiện trừ khi !xuất hiện trong dấu ngoặc kép được thoát bằng dấu gạch chéo ngược. Dấu gạch chéo ngược trước dấu !không bị xóa. Các tham số đặc biệt *@có ý nghĩa đặc biệt khi ở trong dấu ngoặc kép (xem Mở rộng Tham số Shell).

Trong trường hợp cụ thể được hỏi trong câu hỏi, $ COLUMNS là một biến đặc biệt có thuộc tính không chuẩn (xem câu trả lời của lhunath ở trên).


20
Trong trường hợp các dấu ngoặc kép, có thể cách giải quyết này sẽ giúp ích: 'before'"$variable"'after'(như đã nêu trong câu trả lời này: stackoverflow.com/a/13802438/2254346 )
MakisH

Câu trả lời chính xác! Tôi đã gặp vấn đề tương tự khi tham chiếu biến env của mình trong dấu ngoặc kép. Khi tôi thay đổi dấu nháy đơn thành dấu nháy kép, biến env của tôi được mở rộng như mong đợi.
Binita Bharati

14

Lưu ý rằng COLUMNS:

  1. KHÔNG phải là một biến môi trường. Nó là một tham số bash thông thường được đặt bởi chính bash.
  2. Đặt tự động khi nhận được SIGWINCHtín hiệu.

Điểm thứ hai đó thường có nghĩa là COLUMNSbiến của bạn sẽ chỉ được đặt trong trình bao tương tác của bạn , không phải trong tập lệnh bash.

Nếu tập lệnh của bạn stdinđược kết nối với thiết bị đầu cuối, bạn có thể tra cứu chiều rộng của thiết bị đầu cuối theo cách thủ công bằng cách hỏi thiết bị đầu cuối:

tput cols

Và để sử dụng điều này trong lệnh SVN của bạn:

svn diff "$@" --diff-cmd /usr/bin/diff -x "-y -w -p -W $(tput cols)"

(Lưu ý: bạn nên trích dẫn "$@" và tránh xa eval;-))


Cảm ơn vì thông tin; biết chuyện gì đang xảy ra mang lại cảm giác xúc động cho vấn đề.
Jamie

2

Tập lệnh sau phù hợp với tôi cho nhiều giá trị của $COLUMNS. Tôi tự hỏi nếu bạn không thiết lập COLUMNStrước cuộc gọi này?

#!/bin/bash
COLUMNS=30
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

Bạn có thể lặp lại $COLUMNSbên trong tập lệnh của mình để xem nó có được đặt đúng không?


Boo, hiss re: unquotes $@- chia một tham số duy nhất "two words"thành hai tham số riêng biệt, twowords. Nên "$@"chuyển danh sách đối số chính xác như nó đã được đưa ra.
Charles Duffy

0

Bạn đang làm đúng, vì vậy tôi đoán có lỗi gì đó khác (không phải xuất-nhập COLUMNS?).

Một mẹo để gỡ lỗi những trường hợp này là tạo một lệnh chuyên biệt (một lệnh đóng đối với những người sử dụng ngôn ngữ lập trình). Tạo một kịch bản shell có tên là diff-column để thực hiện:

exec /usr/bin/diff -x -y -w -p -W "$COLUMNS" "$@"

và chỉ sử dụng

svn diff "$@" --diff-cmd  diff-columns

Bằng cách này, mã của bạn dễ đọc hơn và dễ đọc hơn (cách tiếp cận từ trên xuống) và bạn có thể kiểm tra mã của các cột khác nhau một cách riêng biệt (cách tiếp cận từ dưới lên).


Dòng lệnh được phân tích cú pháp trước khi quá trình được chia nhỏ, do đó, việc không xuất CỘT không phải là vấn đề.
Peter van der Heijden

1
Anh ấy nói mã của anh ấy là một phần của tập lệnh bash, do đó nó có thể là vấn đề.
Colas Nahaboo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.