tôi có thể viết
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
kết quả cuối cùng đối với tôi dường như giống nhau. Tại sao tôi nên viết cái này hay cái kia? có ai trong số này không di động / POSIX không?
tôi có thể viết
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
kết quả cuối cùng đối với tôi dường như giống nhau. Tại sao tôi nên viết cái này hay cái kia? có ai trong số này không di động / POSIX không?
Câu trả lời:
VAR=$VAR1
là một phiên bản đơn giản hóa của VAR=${VAR1}
. Có những thứ thứ hai có thể làm mà thứ nhất không thể, ví dụ, tham chiếu một chỉ mục mảng (không di động) hoặc loại bỏ một chuỗi con (POSIX-Portable). Xem phần Thêm về các biến của Hướng dẫn Bash cho Người mới bắt đầu và Mở rộng tham số trong thông số POSIX.
Sử dụng dấu ngoặc kép quanh một biến như trong rm -- "$VAR1"
hoặc rm -- "${VAR}"
là một ý tưởng tốt. Điều này làm cho nội dung của biến là một đơn vị nguyên tử. Nếu giá trị biến chứa khoảng trống (tốt, các ký tự trong $IFS
biến đặc biệt, khoảng trống theo mặc định) hoặc ký tự toàn cầu và bạn không trích dẫn nó, thì mỗi từ được xem xét để tạo tên tệp (globalbing) có phần mở rộng tạo ra nhiều đối số cho bất kỳ bạn đang làm
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
Về tính di động: Theo POSIX.1-2008, mục 2.6.2 , các dấu ngoặc nhọn là tùy chọn.
var1=$var
việc mở rộng gây ra lỗi không?
export VAR=$VAR1
. Đối với các dấu ngoặc nhọn, chúng là tùy chọn (kiểm tra đoạn thứ tư của phần bạn đã trích dẫn; đây là trường hợp trong tất cả các vỏ POSIX và POSIX trước).
${VAR}
và $VAR
hoàn toàn tương đương. Đối với việc mở rộng biến đơn giản, lý do duy nhất để sử dụng ${VAR}
là khi phân tích cú pháp sẽ lấy quá nhiều ký tự vào tên biến, như trong ${VAR1}_$VAR2
(không có dấu ngoặc sẽ tương đương với ${VAR1_}$VAR2
). Hầu hết các bản mở rộng được tô điểm ( ${VAR:=default}
,, ${VAR#prefix}
) đều yêu cầu niềng răng.
Trong một phép gán biến, việc tách trường (nghĩa là tách ở khoảng trắng trong giá trị) và mở rộng tên đường dẫn (nghĩa là toàn cầu) bị tắt, do đó, VAR=$VAR1
chính xác tương đương với VAR="$VAR1"
, trong tất cả các vỏ POSIX và trong tất cả các POSIX trước mà tôi đã nghe nói . (POSIX ref: các lệnh đơn giản ). Vì lý do tương tự, VAR=*
đáng tin cậy đặt VAR
chuỗi ký tự *
; tất nhiên VAR=a b
đặt VAR
để a
kể từ khi b
là một từ riêng biệt ở nơi đầu tiên. Nói chung, dấu ngoặc kép là không cần thiết khi cú pháp shell mong đợi một từ duy nhất, ví dụ như trongcase … in
(nhưng không phải trong mẫu), nhưng ngay cả ở đó bạn cũng cần cẩn thận: ví dụ POSIX chỉ định rằngmục tiêu chuyển hướng ( >$filename
) không yêu cầu trích dẫn trong tập lệnh, nhưng một số shell bao gồm bash không yêu cầu dấu ngoặc kép ngay cả trong tập lệnh. Xem Khi nào cần trích dẫn kép? để phân tích kỹ lưỡng hơn.
Bạn cần có dấu ngoặc kép trong các trường hợp khác, đặc biệt là export VAR="${VAR1}"
(có thể viết tương đương export "VAR=${VAR1}"
) trong nhiều shell (POSIX để trường hợp này mở). Sự giống nhau của trường hợp này với các bài tập đơn giản và tính chất phân tán của danh sách các trường hợp bạn không cần dấu ngoặc kép, là lý do tại sao tôi khuyên bạn chỉ nên sử dụng dấu ngoặc kép trừ khi bạn muốn tách và toàn cầu.
IFS
ký tự nào vì tôi muốn theo thói quen. Một ngoại lệ là tôi không trích dẫn giá trị khi thực hiện gán biến (trừ khi được yêu cầu, chẳng hạn như khi giá trị chứa khoảng trắng). Điều này làm cho cú pháp trình chỉnh sửa làm nổi bật hữu ích hơn khi có các lệnh thay thế như FOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Thay vì tô màu mọi thứ màu "chuỗi", tôi nhận được cú pháp tô sáng mã được lồng. Đây cũng là lý do tại sao tôi tránh backticks.
>$file
các tập lệnh POSIX vẫn ổn, nhưng nó không bị lỗi ngay cả khi không tương tác (trừ khi việc tuân thủ POSIX được thi hành với $POSIXLY_CORRECT
hoặc --posix
...).
VAR=$VAR1
, đôi khi tôi đã ngạc nhiên bởi local VAR=$VAR1
, điều mà tôi nhớ là hoạt động khác nhau ở một số khía cạnh, trong ít nhất là một số vỏ. Nhưng atm, tôi không thể tái tạo sự khác biệt.
local VAR=$VAR1
là như thế export VAR=$VAR1
, nó phụ thuộc vào vỏ.
Hãy xem xét rằng trích dẫn kép được sử dụng để mở rộng biến đổi và trích dẫn đơn được sử dụng để trích dẫn mạnh, tức là mở rộng sans.
this='foo'
that='bar'
these="$this"
those='$that'
for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that
Có thể đáng để đề cập rằng bạn nên sử dụng trích dẫn bất cứ khi nào có thể vì một số lý do, trong số đó tốt nhất là nó được coi là thực tiễn tốt nhất và dễ đọc. Ngoài ra bởi vì Bash đôi khi kỳ quặc và thường cho những cách dường như phi logic hoặc không hợp lý / bất ngờ, và thay đổi trích dẫn ngầm định kỳ vọng thành rõ ràng, làm giảm bề mặt lỗi đó (hoặc tiềm năng - cho nó).
Và mặc dù nó hoàn toàn hợp pháp để không trích dẫn, và sẽ hoạt động trong hầu hết các trường hợp, chức năng đó được cung cấp để thuận tiện và có lẽ ít di động hơn. thực hành chính thức đầy đủ được đảm bảo để phản ánh ý định và kỳ vọng là trích dẫn.
Bây giờ cũng xem xét rằng cấu trúc "${somevar}"
được sử dụng cho các hoạt động thay thế. Một số trường hợp sử dụng, chẳng hạn như thay thế và mảng.
thisfile='foobar.txt.bak'
foo="${thisfile%.*}" # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}" # removes longest matching
for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar
foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}" #single occurrence
bar="${foobar//least/most}" #global occurrence (all)
for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful
mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls
alpha=($(ls temp/*))
echo "$alpha" # temp/foo.txt
echo "${alpha}" # temp/foo.txt
echo "${alpha[@]}" # temp/bar.txt temp/foobar.txt temp/foo.txt
echo "${#alpha}" # 12 # length of first element (implicit index [0])
echo "${#alpha[@]}" # 3 # number of elements
echo "${alpha[1]}" # temp/foobar.txt # second element
echo "${#alpha[1])" # 15 # length of second element
for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt
Tất cả điều này hầu như không làm trầy xước bề mặt của "${var}"
cấu trúc thay thế. Tham chiếu dứt khoát cho kịch bản lệnh shell Bash là tham chiếu trực tuyến miễn phí, TLDP Dự án Tài liệu Linuxhttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
ls -la
lrwxrwxrwx. 1 root root 31 Nov 17 13:13 prodhostname
lrwxrwxrwx. 1 root root 33 Nov 17 13:13 testhostname
lrwxrwxrwx. 1 root root 32 Nov 17 13:13 justname
kết thúc sau đó:
env=$1
if [ ! -f /dirname/${env}hostname ]
đáng nói đến như một ví dụ rõ ràng hơn về việc sử dụng curlies