
Esta pregunta tiene dos partes:
(a) Comprender qué está haciendo el código recortado
(b) Comprender la diferencia entreestado de salidayestado de devoluciónen contexto de bash
.
Aquí está el código recortado que estoy tratando de entender:
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
Ejecutar esto produce False
. No puedo entender por qué sucede esto.
Si entiendo esto correctamente, esto es lo que puede estar sucediendo con la if
condición:
(a) var=-2
crea un estado de salida de 0, porque la asignación es un éxito
(b) (( var+=2 ))
suma 2 al valor de var
y la expresión evalúa cero. Entonces el estado de salida es 1 para este término.
(c) 0 && 1 crea un estado de existencia de 0 que luego es utilizado por if
la construcción
Se supone que la if
construcción simplemente verifica el estado de salida y cuando es cero toma elentoncescamino. En el paso (c) anterior es cero pero el script aún toma eldemáscamino. ¿Es esta la forma correcta de entender esto?
Además, sigo viendo bash
el uso de varios textos.estado de salidayestado de devoluciónindistintamente.
Dudo que var=-2
la asignación tenga algún tipo de estado de salida porque no es un programa. Pero cualquier aclaración sobre la diferencia entre dos será genial.
Respuesta1
Eso es:
if
first list of commands
then
second list of commands
else
third list of commands
fi
Eso es ejecutar la segunda lista de comandos si la primera lista de comandos regresa con unverdadero/éxito(cero) estado de salida, es decir, si el último comando de ejecución regresa con un estado de salida cero.
En:
var=-2 && ((var += 2))
Es cmd1 && cmd2
donde cmd2
sólo se ejecuta si cmd1
tiene éxito.
var=-2
Normalmente tendrá éxito siempre que $var
no se haya configurado como de solo lectura, por lo que ((var += 2))
se ejecutará el comando:
((arithmetic expression))
Devolucioneséxito/verdaderosiempre que la expresión se evalúe correctamente (sin errores de sintaxis) y el resultado de la expresión sea distinto de cero.
((123))
,((1 + 1))
,((1 == 1))
devuelve verdadero((0))
,((-2 + 2))
,((2 == -2))
falso retorno.((4294967296 * 4294967296))
devuelve falso en la mayoría de los shells debido al ajuste de enteros de 64 bits
var += 2
como expresión aritmética, realiza la asignación y resuelve el valor que se asigna, aquí 0, de ahí elFALSOestado de salida.
Puede ver el valor en el que se basa el estado de salida utilizando la $((...))
sintaxis de expansión aritmética:
$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0
O asignándolo a una variable:
$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0
$?
contiene el estado de salida del comando anterior. En lo que respecta a /// if
, then
0 significa verdadero, cualquier otra cosa significa falso.else
fi
La confusión aquí proviene del hecho de que para las expresiones aritméticas, es al revés: 0
significa falso y cualquier otra cosa significa verdadero (por ejemplo, 2 == 2
es 1
mientras 2 < 1
es 0
).
Para no preocuparse por la diferencia, olvídese de $?
sus posibles valores. Sólo piensa en términos de booleanos.verdadero/FALSO,éxito/falla.
grep -q foo file
Devuelve verdadero si foo
se encuentra en file
.
[ "$a" = "$b" ]
Devuelve verdadero si $a
contiene lo mismo que $b
.
((6 * 3 - 12))
((4 == 1))
Devuelve verdadero si el resultado de la expresión aritmética es un número distinto de cero.
No importa si esosverdadero/FALSOse expresan en términos de 0 o 1 del estado de salida de esos grep
/ [
comandos o ((...))
construcción.
Respuesta2
(c) 0 && 1 crea un estado de existencia de 0 que luego es utilizado por
if
la construcción
Ahí está el error. 0 && 1 da como resultado 1
. Recuerde que esto no es C ni Java. En el shell 0 && 1 es lo que obtendrías true && false
.
$ true; echo $?
0
$ false; echo $?
1
$ true && false; echo $?
1
Además, sigo viendo que varios textos bash usan el estado de salida y el estado de retorno indistintamente.
Son intercambiables. Lo que debes tener en cuenta es que 0
indica éxito y no 0
indica fracaso. Es lo opuesto a la mayoría de los lenguajes de programación donde 0
es falso y 1
es verdadero.
Respuesta3
Todo está funcionando como se esperaba.
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
Explicación del código: -
if var=-2 && (( var+=2 ))
var=-2 => true
El valor no es cero, por lo que se evalúa como verdadero.
var+=2 => false
El valor es cero, por lo que se evalúa como falso.
esto es como
if true && false
Según cálculo lógicoverdadero && falso => falso
En ese caso aquí está nuestro código final.
if (false)
then
echo "True"
else
echo "False"
fi