¿Cómo evaluará bash el siguiente código?

¿Cómo evaluará bash el siguiente código?

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 ifcondición:

(a) var=-2crea un estado de salida de 0, porque la asignación es un éxito

(b) (( var+=2 ))suma 2 al valor de vary 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 ifla construcción

Se supone que la ifconstrucció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 bashel uso de varios textos.estado de salidayestado de devoluciónindistintamente.

Dudo que var=-2la 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 && cmd2donde cmd2sólo se ejecuta si cmd1tiene éxito.

var=-2

Normalmente tendrá éxito siempre que $varno 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 += 2como 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, then0 significa verdadero, cualquier otra cosa significa falso.elsefi

La confusión aquí proviene del hecho de que para las expresiones aritméticas, es al revés: 0significa falso y cualquier otra cosa significa verdadero (por ejemplo, 2 == 2es 1mientras 2 < 1es 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 foose encuentra en file.

 [ "$a" = "$b" ]

Devuelve verdadero si $acontiene 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 ifla 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 0indica éxito y no 0indica fracaso. Es lo opuesto a la mayoría de los lenguajes de programación donde 0es falso y 1es 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

información relacionada