¿Qué significa “-e” significa en un script bash?

Estoy estudiando el contenido de este archivo preinst que el script ejecuta antes de desempaquetar ese paquete desde su archivo de Debian (.deb).

El script tiene el siguiente código:

#!/bin/bash set -e # Automatically added by dh_installinit if [ "$1" = install ]; then if [ -d /usr/share/MyApplicationName ]; then echo "MyApplicationName is just installed" return 1 fi rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf rm -Rf $HOME/.local/share/file-manager/actions/* fi # End automatically added section 

Mi primera consulta es sobre la línea:

 set -e 

Creo que el rest del guión es bastante simple: verifica si el administrador de paquetes Debian / Ubuntu está ejecutando una operación de instalación. Si es así, verifica si mi aplicación acaba de instalarse en el sistema. Si lo tiene, el script imprime el mensaje “MyApplicationName is just installed” y finaliza ( return 1 significa que termina con un “error”, ¿no?).

Si el usuario le pide al sistema de paquete Debian / Ubuntu que instale mi paquete, el script también elimina dos directorios.

¿Es correcto o me estoy perdiendo algo?

Del help set :

  -e Exit immediately if a command exits with a non-zero status. 

Pero es considerado como una mala práctica por algunas personas (FAQ de bash y personas como las que escriben estas preguntas frecuentes sobre irc freenode #bash), mejor uso:

 trap 'do_something' ERR 

para ejecutar la función do_something cuando se produzcan errores.

Ver http://mywiki.wooledge.org/BashFAQ/105

set -e detiene la ejecución de un script si un comando o canalización tiene un error- que es lo contrario del comportamiento del shell predeterminado, que es ignorar los errores en los scripts. Escriba help set en una terminal para ver la documentación de este comando incorporado.

Según bash: el manual Set Builtin , si -e / errexit está configurado, el shell sale inmediatamente si una tubería consta de un único 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 en la canalización, a menos que la opción de pipefail esté habilitada (está deshabilitada de manera predeterminada).

De ser así, el estado de retorno de la tubería del último comando (más a la derecha) para salir con un estado distinto de cero, o cero si todos los comandos salen exitosamente.

Si desea ejecutar algo al salir, intente definir la 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 simple rastro de la stack :

 onexit(){ while caller $((n++)); do :; done; } 

Hay una opción similar -E / errtrace que podría atrapar ERR, por ejemplo:

 trap onerr ERR 

Ejemplos

Ejemplo de estado cero

 $ true; echo $? 0 

Ejemplo de estado distinto de cero:

 $ false; echo $? 1 

Negar ejemplos de estado:

 $ ! false; echo $? 0 $ false || true; echo $? 0 

Prueba con pipefail estando 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 habilitado:

 $ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $? 1 

Encontré esta pregunta mientras busqué en Google, tratando de 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 aborta 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 script externo) .

Por ejemplo, supongamos que tengo un 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 comandos, mi script externo finaliza con el código de salida del script interno:

 $ ./outer-test.sh $ echo $? 26