O [
comando é um comando comum. Embora a maioria dos shells o forneça como um built-in de eficiência, ela obedece às regras sintáticas normais do shell. [
é exatamente equivalente a test
, exceto que [
requer a ]
como seu último argumento e test
não.
Os colchetes duplos [[ … ]]
são sintaxe especial. Eles foram introduzidos no ksh (vários anos depois [
) porque [
podem ser problemáticos de usar corretamente e [[
permitem algumas novas adições interessantes que usam caracteres especiais do shell. Por exemplo, você pode escrever
[[ $x = foo && $y = bar ]]
porque toda a expressão condicional é analisada pelo shell, enquanto [ $x = foo && $y = bar ]
que primeiro seria dividida em dois comandos [ $x = foo
e $y = bar ]
separada pelo &&
operador. Da mesma forma, colchetes duplos permitem coisas como a sintaxe de correspondência de padrões, por exemplo, [[ $x == a* ]]
para testar se o valor de x
começa com a
; entre colchetes, isso seria expandido a*
para a lista de arquivos cujos nomes começam a
no diretório atual. Os colchetes duplos foram introduzidos pela primeira vez no ksh e só estão disponíveis no ksh, bash e zsh.
Dentro de colchetes, você precisa usar aspas duplas em torno de substituições de variáveis, como na maioria dos outros lugares, porque são apenas argumentos para um comando (que por acaso é o [
comando). Dentro de colchetes duplos, você não precisa de aspas duplas, porque o shell não divide ou brilha palavras: está analisando uma expressão condicional, não um comando.
Uma exceção, porém, é [[ $var1 = "$var2" ]]
onde você precisa das aspas, se desejar fazer uma comparação de cadeias de bytes a bytes, caso contrário, $var2
seria um padrão com o qual comparar $var1
.
Uma coisa que você não pode fazer [[ … ]]
é usar uma variável como operador. Por exemplo, isso é perfeitamente legal (mas raramente útil):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
No seu exemplo
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
o comando dentro do if
é [
com os 4 argumentos -d
, /home/mazimi/VirtualBox
, VMs
e ]
. O shell analisa -d /home/mazimi/VirtualBox
e depois não sabe o que fazer VMs
. Você precisaria impedir a divisão de palavras ${dir}
para obter um comando bem formado.
De um modo geral, sempre use aspas duplas em torno de substituições de variáveis e comandos, a menos que você saiba que deseja executar a divisão e a observação de palavras no resultado. Os principais locais onde é seguro não usar aspas duplas são:
- em uma atribuição:
foo=$bar
(mas observe que você precisa de aspas duplas em export "foo=$bar"
ou em atribuições de matriz como array=("$a" "$b")
);
- em uma
case
declaração case $foo in …
:;
- dentro de colchetes duplos, exceto no lado direito da
=
ou ==
operador (a menos que você deseja fazer a correspondência de padrões): [[ $x = "$y" ]]
.
Em tudo isso, é correto usar aspas duplas, assim você pode pular as regras avançadas e usá-las o tempo todo.