O comando [
é um comando comum. Embora a maioria das shells a forneça como um built-in para eficiência, ela obedece às regras sintáticas normais da shell. [
é exatamente equivalente a test
, exceto que [
requer um ]
como seu último argumento e test
não.
Os colchetes duplos [[ … ]]
são sintaxe especial. Eles foram introduzidos em ksh (vários anos depois de [
) porque [
pode ser problemático para usar corretamente e [[
permite algumas novas adições 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 ]
primeiro seria dividido em dois comandos [ $x = foo
e $y = bar ]
separados pelo operador &&
. Similarmente, 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
; em colchetes, isso expandiria a*
para a lista de arquivos cujos nomes começam com a
no diretório atual. Os colchetes duplos foram introduzidos pela primeira vez em ksh e estão disponíveis apenas em ksh, bash e zsh.
Dentro de colchetes únicos, você precisa usar aspas duplas em torno das substituições de variáveis, como na maioria dos outros lugares, porque elas são apenas argumentos para um comando (que é o comando [
). Dentro de colchetes duplos, você não precisa de aspas duplas, porque o shell não faz divisão de palavras ou globbing: está analisando uma expressão condicional, não um comando.
Uma exceção é [[ $var1 = "$var2" ]]
, em que você precisa das aspas se quiser fazer uma comparação de cadeia de byte a byte, caso contrário, $var2
seria um padrão para corresponder a $var1
contra.
Uma coisa que você não pode fazer com [[ … ]]
é 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 de if
é [
com os 4 argumentos -d
, /home/mazimi/VirtualBox
, VMs
e ]
. O shell analisa -d /home/mazimi/VirtualBox
e, em seguida, não sabe o que fazer com VMs
. Você precisaria evitar que a divisão de palavras em ${dir}
obtenha um comando bem formado.
De um modo geral, use sempre aspas duplas em torno das substituições de variáveis e comandos, a menos que você saiba que deseja executar a divisão de palavras e globbing no resultado. Os principais lugares onde é seguro não usar as aspas duplas são:
- em uma atribuição:
foo=$bar
(mas observe que você precisa das aspas duplas em export "foo=$bar"
ou em atribuições de matriz como array=("$a" "$b")
);
- em uma instrução
case
: case $foo in …
;
- entre colchetes duplos, exceto no lado direito do operador
=
ou ==
(a menos que você queira correspondência de padrões): [[ $x = "$y" ]]
.
Em todos eles, é correto usar aspas duplas, então você pode ignorar as regras avançadas e usar as aspas o tempo todo.