Al desreferenciar una variable bash, debe usar $signo. Sin embargo, parece que lo siguiente está funcionando bien:
x=5
[[ x -gt 2 ]]
¿Alguien puede explicar esto?
Editar: (más información)
Lo que quiero decir es cómo y por qué el comando [[]] está desreferenciando mi variable x sin el signo $. Y sí, si x = 1, la declaración se evalúa como falsa (estado de retorno 1)
bash
bash-expansion
Invitado
fuente
fuente

x=1sigue[[ x -gt 2]]?Respuestas:
La razón es que
-eqobliga a una evaluación aritmética de los argumentos.Un operador aritmético:
-eq,-gt,-lt,-ge,-ley-nedentro de una[[ ]](en ksh, zsh y bash) medios para expandir automáticamente los nombres de variables como en el lenguaje C, no necesita de un líder$.Para la confirmación debemos buscar en el código fuente de bash. El manual no ofrece confirmación directa .
Dentro
test.cdel procesamiento de operadores aritméticos entran en esta función:Donde
sytson ambos operandos. Los operandos se entregan a esta función:La función
evalexpse define dentroexpr.c, que tiene este encabezado:Entonces, sí, ambos lados de un operador aritmético caen (directamente) en la evaluación de expresiones aritméticas. Directamente, sin peros, sin peros.
En la práctica, con:
Ambos fallan:
Lo cual es correcto,
xno se está expandiendo yxno es igual a un número.Sin embargo:
La variable nombrada
xse expande (incluso sin un $).Esto no sucede para un
[…]en zsh o bash (lo hace en ksh).Eso es lo mismo que sucede dentro de un
$((…)):Y, por favor, comprenda que esto es (muy) recursivo (excepto en guión y guión):
A 😮
Y bastante arriesgado:
El error de sintaxis podría evitarse fácilmente:
Como dice el refrán: desinfecte su aporte
fin de 😮
Tanto el (más antiguo) externo
/usr/bin/test(no el incorporadotest) como el aún más antiguo y también externoexprno expanden las expresiones solo enteros (y aparentemente, solo enteros decimales):fuente
[[una palabra clave, los operadores y los operandos se detectan cuando se lee el comando y no después de la expansión. De este modo[[se puede tratar-eqde una manera más inteligente que, por ejemplo,[. Pero lo que me pregunto es: ¿dónde podemos encontrar documentación sobre la lógica que utiliza bash para interpretar comandos compuestos? No me parece muy obvio y aparentemente no puedo encontrar explicaciones satisfactorias enmanoinfo bash.testsección de los operadores aritméticos man zshbuiltins que esperan argumentos enteros en lugar de expresiones aritméticas . Lo que confirma que algunos argumentos son tratados como expresiones aritméticas por la prueba incorporada en condiciones no especificadas en esta cita. Voy a confirmo con el código fuente ... ....Los operandos de las comparaciones numéricas
-eq,-gt,-lt,-ge,-ley-nese toman como expresiones aritméticas. Con alguna limitación, todavía necesitan ser palabras de shell único.El comportamiento de los nombres de variables en la expresión aritmética se describe en Shell Arithmetic :
y también:
Pero en realidad no puedo encontrar la parte de la documentación donde se dice que las comparaciones numéricas toman expresiones aritméticas. No se describe en Construcciones condicionales
[[, ni se describe en Expresiones condicionales bash .Pero, por experimento, parece funcionar como se dijo anteriormente.
Entonces, cosas como esta funcionan:
esto también (se evalúa el valor de la variable):
Pero esto no; no es una sola palabra de shell cuando
[[ .. ]]se analiza, por lo que hay un error de sintaxis en el condicional:En otros contextos aritméticos, no es necesario que la expresión no tenga espacios en blanco. Esto se imprime
999, ya que los corchetes delimitan inequívocamente la expresión aritmética en el índice:Por otro lado, la
=comparación es una coincidencia de patrones y no implica aritmética, ni la expansión automática de variables realizada en un contexto aritmético (Construcciones condicionales):Entonces esto es falso ya que las cadenas son obviamente diferentes:
como es esto, a pesar de que los valores numéricos son los mismos:
y aquí, también, las cadenas (
xy6) se comparan, son diferentes:Sin embargo, esto expandiría la variable, así que esto es cierto:
fuente
arg1 OP arg2dice que los argumentos pueden ser enteros positivos o negativos, lo que supongo que implica que se tratan como expresiones aritméticas. Confusamente, también implica que no pueden ser cero. :)[, y allí no son expresiones aritméticas. En cambio, Bash se queja de los no enteros.[es un comando externo, no tiene acceso a variables de shell. A menudo se optimiza con un comando incorporado, pero aún se comporta igual.[tanto como a[[. Incluso con[, los operandos-eqy amigos son / tienen que ser enteros, por lo que esa descripción también se aplica. Tomar "debe ser enteros" para significar "se interpretan como expresiones aritméticas" no se aplica en ambos casos. (Probablemente, al menos en parte debido a[que actúa como un comando normal, como usted dice.)Sí, su observación es correcta, la expansión de la variable se realiza en expresiones entre corchetes dobles
[[ ]], por lo que no necesita poner$delante de un nombre de variable.Esto se establece explícitamente en el
bashmanual:Tenga en cuenta que este no es el caso de la versión de un solo parche
[ ], ya[que no es una palabra clave de shell (sintaxis), sino más bien un comando (en bash está integrado, otros shells podrían usar externo, alineado para probar).fuente
(x=1; [[ $x = 1 ]]; echo $?)retornos0,(x=1; [[ x = 1 ]]; echo $?)retornos1, es decir, la expansión de parámetros no se realizaxcuando comparamos cadenas. Este comportamiento se parece a la evaluación aritmética desencadenada por la expansión aritmética, es decir, lo que sucede en(x=1; echo $((x+1))). (Acerca de la evaluación aritmética,man bashestablece que "Dentro de una expresión, las variables de shell también pueden ser referenciadas por nombre sin usar la sintaxis de expansión de parámetros).-gtoperador espera un número, la expresión completa se reevalúa como si estuviera dentro(()), por otro lado,==espera cadenas, por lo que se activa la función de coincidencia de patrones. No busqué en el código fuente, pero suena razonable.[es un caparazón incorporado en bash.