El script Bash con `set -e` no se detiene en el comando `... && ...`

El script Bash con `set -e` no se detiene en el comando `... && ...`

Yo uso set -eparadetener el script bash en el primer error.

Todo funciona bien a menos que use el comando con &&:

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

comparado con:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

El primer ejemplo todavía resuena I'm running!, pero el segundo no. ¿Por qué se comportan de manera diferente?

UPD. Pregunta similar:https://stackoverflow.com/questions/6930295/set-e-and-short-tests

Respuesta1

Este es un comportamiento documentado. Elpágina de manual de bash(1)dice, porset -e,

El shell no se cierra si el comando que falla es parte de la lista de comandos inmediatamente después de una palabra clave whileo until, parte de la prueba que sigue a las palabras reservadas ifo ,elifparte de cualquier comando ejecutado en una lista &&o|| excepto el comando que sigue al final &&o||, cualquier comando en una canalización excepto el último, o si el valor de retorno del comando se invierte con !.
[Énfasis añadido.]

Y elPOSIXLenguaje de comandos de shellEspecificación confirma que este es el comportamiento correcto:

La -econfiguración se ignorará al ejecutar la lista compuesta que sigue a while, until, ifo elifpalabra reservada, una canalización que comienza con la !palabra reservada o cualquier comando de una lista AND-OR que no sea el último.

ySección 2.9.3Lizade ese documento define

Una lista AND-OR es una secuencia de una o más canalizaciones separadas por los operadores " &&" y " ||" .

Respuesta2

La set -eopción no tiene efecto en algunas situaciones y este es el comportamiento estándar y portátil en un shell compatible con POSIX.


El comando fallido es parte de la canalización:

false | true; echo printed

imprimirá printed.

Y solo se considera el fallo de la propia tubería:

true | false; echo 'not printed'

no imprimirá nada.


El comando fallido se ejecuta en la lista compuesta que sigue a la palabra reservada while, until, if, elifuna canalización que comienza con la !palabra reservada o cualquier comando como parte de &&una ||lista excepto el último:

false || true; echo printed

El último comando falla y aún así se ve set -eafectado:

true && false; echo 'not printed'

Elsubcapafalla en un comando compuesto:

(false; echo 'not printed') | cat -; echo printed

Respuesta3

Supongo que la condición si-entonces en su conjunto se evalúa como verdadera.

Lo intenté

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

quien da

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

El código de error se detecta mediante la condición if, por lo que bash no activará el final de la ejecución.

información relacionada