Desde help set
:
-e Exit immediately if a command exits with a non-zero status.
Pero algunos lo consideran una mala práctica (autores de preguntas frecuentes de bash y de preguntas frecuentes de irc freenode #bash). Se recomienda utilizar:
trap 'do_something' ERR
ejecutar do_something
función cuando se producen errores.
Consulte http://mywiki.wooledge.org/BashFAQ/105
set -e
detiene la ejecución de una secuencia de comandos si un comando o canalización tiene un error, que es lo opuesto al comportamiento predeterminado del shell, que consiste en ignorar los errores en las secuencias de comandos. Escribe help set
en una terminal para ver la documentación de este comando incorporado.
Según bash:el manual de Set Builtin, si -e
/errexit
está configurado, el shell sale inmediatamente si una canalización que consta de un solo comando simple, una lista o un comando compuesto devuelve un estado distinto de cero.
De forma predeterminada, el estado de salida de una canalización es el estado de salida del último comando de la canalización, a menos que pipefail
la opción está habilitada (está deshabilitada de manera predeterminada).
Si es así, el estado de retorno de la canalización del último comando (más a la derecha) para salir con un estado distinto de cero, o cero si todos los comandos salen correctamente.
Si desea ejecutar algo al salir, intente definir trap
, por ejemplo:
trap onexit EXIT
donde onexit
es su función para hacer algo al salir, como a continuación, que está imprimiendo el seguimiento de pila simple:
onexit(){ while caller $((n++)); do :; done; }
Hay una opción similar -E
/errtrace
que atraparía en ERR en su lugar, por ejemplo:
trap onerr ERR
Ejemplos
Ejemplo de estado cero:
$ true; echo $?
0
Ejemplo de estado distinto de cero:
$ false; echo $?
1
Ejemplos de estado de negación:
$ ! false; echo $?
0
$ false || true; echo $?
0
Prueba con pipefail
estar deshabilitado:
$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1
Prueba con pipefail
siendo habilitado:
$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
Encontré esta publicación mientras intentaba averiguar cuál era el estado de salida de un script que se canceló debido a un set -e
. La respuesta no me pareció obvia; de ahí esta respuesta. Básicamente, set -e
cancela la ejecución de un comando (por ejemplo, un script de shell) y devuelve el código de estado de salida del comando que falló (es decir, el script interno, no el externo) .
Por ejemplo, supongamos que tengo el script de shell outer-test.sh
:
#!/bin/sh
set -e
./inner-test.sh
exit 62;
El código para inner-test.sh
es:
#!/bin/sh
exit 26;
Cuando ejecuto outer-script.sh
desde la línea de comando, mi secuencia de comandos externa termina con el código de salida de la secuencia de comandos interna:
$ ./outer-test.sh
$ echo $?
26