¿Hay alguna diferencia entre estos dos?
[[ $a == z* ]]
y
[ $a == z* ]
¿Puedo tener un ejemplo donde tendrían diferentes salidas?
Además, ¿cómo funciona el funcionamiento de [[ ]]
difiere de [ ]
?
Respuesta aceptada:
La diferencia entre [[ … ]]
y [ … ]
se cubre principalmente en ¿Por qué la expansión de parámetros con espacios sin comillas funciona dentro de corchetes dobles “[[” pero no dentro de corchetes simples “[“?.
Crucialmente, [[ … ]]
es una sintaxis especial, mientras que [
es un nombre divertido para un comando. [[ … ]]
tiene reglas de sintaxis especiales para lo que hay dentro, [ … ]
no.
Con el añadido de un comodín, así es como [[ $a == z* ]]
se evalúa:
- Analice el comando:este es el
[[ … ]]
construcción condicional alrededor de la expresión condicional$a == z*
. - Analizar la expresión condicional:este es el
==
operador binario, con los operandos$a
yz*
. - Expande el primer operando en el valor de la variable
a
. - Evaluar el
==
operador:prueba si el valor de la variablea
coincide con el patrónz*
. - Evaluar la expresión condicional:su resultado es el resultado del operador condicional.
- El comando ahora se evalúa, su estado es 0 si la expresión condicional era verdadera y 1 si era falsa.
Así es como [ $a == z* ]
se evalúa:
- Analice el comando:este es el
[
comando con los argumentos formados al evaluar las palabras$a
,==
,z*
,]
. - Expandir
$a
en el valor de la variablea
. - Realice la división de palabras y la generación de nombres de archivo en los parámetros del comando.
- Por ejemplo, si el valor de
a
es la cadena de 6 caracteresfoo b*
(obtenido por ejemplo,a='foo b*'
) y la lista de archivos en el directorio actual es (bar
,baz
,qux
,zim
,zum
), entonces el resultado de la expansión es la siguiente lista de palabras:[
,foo
,bar
,baz
,==
,zim
,zum
,]
.
- Por ejemplo, si el valor de
- Ejecute el comando
[
con los parámetros obtenidos en el paso anterior.- Con los valores de ejemplo anteriores, el
[
comando se queja de un error de sintaxis y devuelve el estado 2.
- Con los valores de ejemplo anteriores, el
Nota:En [[ $a == z* ]]
, en el paso 3, el valor de a
no se somete a la división de palabras ni a la generación de nombres de archivo, porque se encuentra en un contexto en el que se espera una sola palabra (el argumento de la izquierda del operador condicional ==
). En la mayoría de los casos, si una sola palabra tiene sentido en esa posición, la expansión variable se comporta como si estuviera entre comillas dobles. Sin embargo, hay una excepción a esa regla:en [[ abc == $a ]]
, si el valor de a
contiene comodines, luego abc
se compara con el patrón comodín. Por ejemplo, si el valor de a
es a*
entonces [[ abc == $a ]]
es verdadero (porque el comodín *
proveniente de la expansión sin comillas de $a
coincide con bc
) mientras que [[ abc == "$a" ]]
es falso (porque el carácter ordinario *
proveniente de la expansión citada de $a
no coincide con bc
). Dentro de [[ … ]]
, las comillas dobles no marcan la diferencia, excepto en el lado derecho de los operadores de coincidencia de cadenas (=
, ==
, !=
y =~
).