Команда [
это обычная команда. Хотя большинство оболочек предоставляют его как встроенный для эффективности, он подчиняется нормальным синтаксическим правилам оболочки. [
в точности эквивалентно 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" ]]
.
Во всех этих случаях правильно использовать двойные кавычки, так что вы можете также пропустить расширенные правила и использовать кавычки все время.