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à testkhô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 = foovà đượ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ị xbắ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 atrong 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, $var2sẽ là một mẫu để khớp $var1vớ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 iflà [với 4 đối số -d, /home/mazimi/VirtualBox, VMsvà ]. Shell phân tích cú pháp -d /home/mazimi/VirtualBoxvà 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
casetuyê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.