Các [
lệnh là một lệnh thông thường. Mặc dù hầu hết các shell cung cấp cho nó như là một tích hợp cho hiệu quả, nó tuân theo các quy tắc cú pháp thông thường của shell. [
là chính xác tương đương test
, ngoại trừ [
yêu cầu ]
như là đối số cuối cùng của nó và test
không.
Dấu ngoặc kép [[ … ]]
là cú pháp đặc biệt. Chúng được giới thiệu trong ksh (vài năm sau [
) vì [
có thể gây rắc rối khi sử dụng chính xác và [[
cho phép một số bổ sung mới tốt đẹp sử dụng các ký tự đặc biệt shell. Ví dụ, bạn có thể viết
[[ $x = foo && $y = bar ]]
bởi vì toàn bộ biểu thức điều kiện được phân tách bằng shell, trong khi [ $x = foo && $y = bar ]
trước tiên sẽ được tách thành hai lệnh [ $x = foo
và được $y = bar ]
phân tách bởi &&
toán tử. Tương tự dấu ngoặc kép cho phép những thứ như cú pháp khớp mẫu, ví dụ [[ $x == a* ]]
để kiểm tra xem giá trị x
bắt đầu bằng a
; trong dấu ngoặc đơn, điều này sẽ mở rộng a*
sang danh sách các tệp có tên bắt đầu a
trong thư mục hiện tại. Dấu ngoặc kép được giới thiệu lần đầu tiên trong ksh và chỉ có sẵn trong ksh, bash và zsh.
Trong dấu ngoặc đơn, bạn cần sử dụng dấu ngoặc kép xung quanh các thay thế khác nhau, như ở hầu hết các vị trí khác, vì chúng chỉ là đối số của một lệnh (điều này xảy ra là [
lệnh). Trong dấu ngoặc kép, bạn không cần dấu ngoặc kép, vì shell không thực hiện phân tách từ hoặc tạo khối: nó phân tích một biểu thức điều kiện, không phải là lệnh.
Mặc dù vậy, một ngoại lệ là [[ $var1 = "$var2" ]]
nơi bạn cần dấu ngoặc kép nếu bạn muốn thực hiện so sánh chuỗi byte-byte, nếu không, $var2
sẽ là một mẫu để khớp $var1
với.
Một điều bạn không thể làm [[ … ]]
là sử dụng một biến như một toán tử. Ví dụ: điều này là hoàn toàn hợp pháp (nhưng hiếm khi hữu ích):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
Trong ví dụ của bạn
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
lệnh bên trong if
là [
với 4 đối số -d
, /home/mazimi/VirtualBox
, VMs
và ]
. Shell phân tích cú pháp -d /home/mazimi/VirtualBox
và sau đó không biết phải làm gì với VMs
. Bạn sẽ cần phải ngăn chặn việc chia tách từ ${dir}
để có được một lệnh được hình thành tốt.
Nói chung, luôn luôn sử dụng dấu ngoặc kép xung quanh các thay thế biến và lệnh trừ khi bạn biết bạn muốn thực hiện chia tách từ và kết quả trên kết quả. Những nơi chính mà an toàn không sử dụng dấu ngoặc kép là:
- trong một bài tập:
foo=$bar
(nhưng lưu ý rằng bạn cần dấu ngoặc kép trong export "foo=$bar"
hoặc trong các bài tập mảng như array=("$a" "$b")
);
- trong một
case
tuyên bố : case $foo in …
;
- bên trong dấu ngoặc kép ngoại trừ ở phía bên phải của toán tử
=
hoặc ==
toán tử (trừ khi bạn muốn khớp mẫu) : [[ $x = "$y" ]]
.
Trong tất cả những điều này, việc sử dụng dấu ngoặc kép là chính xác, vì vậy bạn cũng có thể bỏ qua các quy tắc nâng cao và sử dụng dấu ngoặc kép mọi lúc.