El [
comando es un comando ordinario. Aunque la mayoría de los shells lo proporcionan como una eficiencia incorporada, obedece las reglas sintácticas normales del shell. [
es exactamente equivalente a test
, excepto que [
requiere un ]
como último argumento y test
no lo hace.
Los corchetes dobles [[ … ]]
son sintaxis especial. Se introdujeron en ksh (varios años después [
) porque [
puede ser problemático de usar correctamente y [[
permite algunas nuevas adiciones agradables que usan caracteres especiales de shell. Por ejemplo, puedes escribir
[[ $x = foo && $y = bar ]]
porque toda la expresión condicional es analizada por el shell, mientras [ $x = foo && $y = bar ]
que primero se dividiría en dos comandos [ $x = foo
y se $y = bar ]
separaría por el &&
operador. Del mismo modo, los corchetes dobles permiten cosas como la sintaxis de coincidencia de patrones, por ejemplo, [[ $x == a* ]]
para probar si el valor de x
comienza con a
; entre paréntesis, esto se expandiría a*
a la lista de archivos cuyos nombres comienzan a
en el directorio actual. Los corchetes dobles se introdujeron por primera vez en ksh y solo están disponibles en ksh, bash y zsh.
Dentro de los corchetes simples, debe usar comillas dobles alrededor de sustituciones variables, como en la mayoría de los otros lugares, porque son solo argumentos para un comando (que resulta ser el [
comando). Dentro de los corchetes dobles, no necesita comillas dobles, ya que el shell no divide ni engloba palabras: analiza una expresión condicional, no un comando.
Sin embargo, una excepción es [[ $var1 = "$var2" ]]
cuando necesita las comillas si desea hacer una comparación de cadena byte a byte, de lo contrario, $var2
sería un patrón para comparar $var1
.
Una cosa que no puede hacer [[ … ]]
es usar una variable como operador. Por ejemplo, esto es perfectamente legal (pero rara vez útil):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
En tu ejemplo
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
el comando dentro de la if
es [
con los 4 argumentos -d
, /home/mazimi/VirtualBox
, VMs
y ]
. El shell analiza -d /home/mazimi/VirtualBox
y luego no sabe qué hacer VMs
. Debería evitar la división de palabras ${dir}
para obtener un comando bien formado.
En términos generales, siempre use comillas dobles alrededor de las sustituciones de variables y comandos a menos que sepa que desea dividir y pegar palabras en el resultado. Los principales lugares donde es seguro no usar las comillas dobles son:
- en una asignación:
foo=$bar
(pero tenga en cuenta que necesita las comillas dobles en export "foo=$bar"
o en asignaciones de matriz como array=("$a" "$b")
);
- en una
case
declaración: case $foo in …
;
- dentro de los paréntesis dobles excepto en el lado derecho del
=
o de ==
operador (a menos que usted desea que la coincidencia de patrones): [[ $x = "$y" ]]
.
En todo esto, es correcto usar comillas dobles, por lo que es mejor omitir las reglas avanzadas y usar las comillas todo el tiempo.