Команда [это обычная команда. Хотя большинство оболочек предоставляют его как встроенный для эффективности, он подчиняется нормальным синтаксическим правилам оболочки. [в точности эквивалентно test, за исключением того, что [требует в ]качестве последнего аргумента a и testне делает.
Двойные скобки [[ … ]]имеют специальный синтаксис. Они были введены в ksh (через несколько лет [), потому что их использование [может быть проблематичным и [[допускает некоторые новые приятные дополнения, которые используют специальные символы оболочки. Например, вы можете написать
[[ $x = foo && $y = bar ]]
потому что все условное выражение анализируется оболочкой, тогда как [ $x = foo && $y = bar ]сначала будет разделено на две команды [ $x = fooи $y = bar ]разделены &&оператором. Точно так же двойные скобки позволяют такие вещи, как синтаксис сопоставления с образцом, например, [[ $x == a* ]]чтобы проверить, xначинается ли значение с a; в одиночных скобках это расширит a*список файлов, имена которых начинаются с aтекущего каталога. Двойные скобки были впервые введены в ksh и доступны только в ksh, bash и zsh.
Внутри одинарных скобок необходимо использовать двойные кавычки вокруг подстановок переменных, как и в большинстве других мест, потому что они являются просто аргументами команды (которая является [командой). Внутри двойных скобок вам не нужны двойные кавычки, потому что оболочка не разбивает и не разбивает слова: она разбирает условное выражение, а не команду.
Исключением являются случаи, [[ $var1 = "$var2" ]]когда вам нужны кавычки, если вы хотите сделать сравнение строк в байтах, в противном случае $var2это будет образец для $var1сравнения.
Одна вещь, которую вы не можете сделать, [[ … ]]это использовать переменную в качестве оператора. Например, это совершенно законно (но редко полезно):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
В вашем примере
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
команда внутри ifесть [с 4 -х аргументов -d, /home/mazimi/VirtualBox, VMsи ]. Оболочка разбирает -d /home/mazimi/VirtualBoxи потом не знает что делать VMs. Вы должны были бы предотвратить разделение слов, ${dir}чтобы получить правильно сформированную команду.
Вообще говоря, всегда используйте двойные кавычки вокруг подстановок переменных и команд, если только вы не знаете, что хотите выполнить разбиение слов и глобализацию результата. Основные места, где нельзя использовать двойные кавычки:
- в присваивании:
foo=$bar(но учтите, что вам нужны двойные кавычки в export "foo=$bar"или в присваиваниях массива, как array=("$a" "$b"));
- в
caseзаявлении case $foo in …:;
- в двойных скобках , за исключением на правой стороне
=или ==оператора (если вы не хотите делать сопоставления с образцом): [[ $x = "$y" ]].
Во всех этих случаях правильно использовать двойные кавычки, так что вы можете также пропустить расширенные правила и использовать кавычки все время.