Estoy estudiando el contenido de este archivo de preinst que el script ejecuta antes de que el paquete se desempaquete de 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 sectionMi primera consulta es sobre la línea:
set -eCreo que el resto del script es bastante simple: comprueba si el administrador de paquetes Debian / Ubuntu está ejecutando una operación de instalación. Si es así, comprueba si mi aplicación acaba de instalarse en el sistema. Si es así, el script imprime el mensaje "MyApplicationName se acaba de instalar" y finaliza ( return 1significa que termina con un "error", ¿no?).
Si el usuario solicita al sistema de paquetes Debian / Ubuntu que instale mi paquete, el script también elimina dos directorios.
¿Es correcto o me estoy perdiendo algo?

man setset +eRespuestas:
De
help set:Pero algunos lo consideran una mala práctica (preguntas frecuentes sobre bash y autores de preguntas frecuentes sobre irc freenode #bash). Se recomienda usar:
para ejecutar la
do_somethingfunción cuando se producen errores.Ver http://mywiki.wooledge.org/BashFAQ/105
fuente
trap 'exit' ERRERRtrampa no es heredada por las funciones de shell, por lo que si tiene funciones,set -o errtraceoset -Ele permitirá establecer la trampa una vez y aplicarla globalmente.trap 'exit' ERRhacer nada diferente deset -e?set -edetiene la ejecución de un script si un comando o canalización tiene un error, que es lo opuesto al comportamiento predeterminado del shell, que es ignorar los errores en los scripts. Escribahelp setun terminal para ver la documentación de este comando incorporado.fuente
set -o pipefailque se puede usar para propagar errores, de modo que el valor de retorno del comando de canalización no sea cero si uno de los comandos anteriores salió con un estado distinto de cero.-o pipefailsolo significa que el estado de salida del primer-o errexitcomando distinto de cero (es decir, error en términos) de la tubería se propaga hasta el final. Los comandos restantes en la tubería aún se ejecutan , incluso conset -o errexit. Por ejemplo:echo success | cat - <(echo piping); echo continues, dondeecho successrepresenta un éxito, pero comando falibles, se imprimirásuccess,pipingycontinues, sin embargofalse | cat - <(echo piping); echo continues, lafalseque representa el comando ahora erroring en silencio, todavía se imprimapipingantes de salir.Según bash: el manual Set Builtin , si
-e/errexitestá configurado, el shell sale inmediatamente si una tubería que consiste en un solo comando simple , una lista o un comando compuesto devuelve un estado distinto de cero.Por defecto, el estado de salida de una tubería es el estado de salida del último comando en la tubería, a menos que la
pipefailopción esté habilitada (está deshabilitada de manera predeterminada).Si es así, el estado de retorno de la tubería del último comando (el más a la derecha) para salir con un estado distinto de cero, o cero si todos los comandos salen con éxito.
Si desea ejecutar algo al salir, intente definir
trap, por ejemplo:¿Dónde
onexitestá su función para hacer algo al salir, como a continuación, que está imprimiendo el rastro simple de la pila :Hay una opción similar
-E/errtraceque atraparía en ERR en su lugar, por ejemplo:Ejemplos
Ejemplo de estado cero:
Ejemplo de estado distinto de cero:
Ejemplos de estado de negación:
Prueba con
pipefailser deshabilitado:Prueba con
pipefailestar habilitado:fuente
Encontré esta publicación mientras intentaba averiguar cuál era el estado de salida de un script que fue abortado debido a un
set -e. La respuesta no me pareció obvia; De ahí esta respuesta. Básicamente,set -eaborta 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 el script de shell
outer-test.sh:El código para
inner-test.shes:Cuando ejecuto
outer-script.shdesde la línea de comandos, mi script externo termina con el código de salida del script interno:fuente
Creo que la intención es que el guión en cuestión falle rápidamente.
Para probar esto usted mismo, simplemente escriba
set -een un indicador de bash. Ahora, intenta correrls. Obtendrá un listado de directorio. Ahora, escribelsd. Ese comando no se reconoce y devolverá un código de error, por lo que su solicitud de bash se cerrará (debido aset -e).Ahora, para comprender esto en el contexto de un 'script', use este script simple:
Si lo ejecuta como está, obtendrá el listado del directorio
lsen la última línea. Si descomentaset -ey vuelve a ejecutar, no verá la lista del directorio ya que bash detiene el procesamiento una vez que encuentra el error delsd.fuente
Esta es una vieja pregunta, pero ninguna de las respuestas aquí discute el uso de
set -eakaset -o errexiten los scripts de manejo de paquetes de Debian. El uso de esta opción es obligatorio. en estos scripts, según la política de Debian; la intención aparentemente es evitar cualquier posibilidad de una condición de error no controlada.Lo que esto significa en la práctica es que debe comprender en qué condiciones los comandos que ejecuta podrían devolver un error y manejar cada uno de esos errores explícitamente.
Los errores comunes son, por ejemplo,
diff(devuelve un error cuando hay una diferencia) ygrep(devuelve un error cuando no hay coincidencia). Puede evitar los errores con el manejo explícito:(Observe también cómo nos encargamos de incluir el nombre del script actual en el mensaje y de escribir mensajes de diagnóstico en un error estándar en lugar de en la salida estándar).
Si no es realmente necesario o útil un manejo explícito, explícitamente no haga nada:
(El uso de la cáscara
:comando no-op es un poco oscuro, pero se ve con bastante frecuencia).Solo para reiterar,
es taquigrafía para
es decir, explícitamente decimos que
otherdebe ejecutarse si y solo sisomethingfalla. La escritura manualif(y otras declaraciones de control de flujo de shell comowhile,until) también es una forma válida de manejar un error (de hecho, si no fuera así, los scripts de shell conset -enunca podrían contener declaraciones de control de flujo!)Y también, solo para ser explícito, en ausencia de un controlador como este,
set -ecausaría que todo el script falle inmediatamente con un error sidiffencuentra una diferencia o sigrepno encuentra una coincidencia.Por otro lado, algunos comandos no producen un estado de salida de error cuando desea que lo hagan. Los comandos comúnmente problemáticos son
find(el estado de salida no refleja si realmente se encontraron archivos) ysed(el estado de salida no revelará si el script recibió alguna entrada o si realizó algún comando con éxito). Una protección simple en algunos escenarios es canalizar a un comando que grita si no hay salida:Cabe señalar que el estado de salida de una tubería es el estado de salida del último comando en esa tubería. Entonces, los comandos anteriores enmascaran completamente el estado de
findysed, y solo le dicen sigrepfinalmente tuvo éxito.(Bash, por supuesto, sí
set -o pipefail; pero los scripts de paquetes de Debian no pueden usar las funciones de Bash. La política dicta firmemente el uso de POSIXshpara estos scripts, aunque esto no siempre fue así).En muchas situaciones, esto es algo a tener en cuenta por separado cuando se codifica a la defensiva. A veces tiene que, por ejemplo, pasar por un archivo temporal para poder ver si el comando que produjo esa salida finalizó con éxito, incluso cuando la expresión idiomática y la conveniencia de otro modo le indicarían que usara una tubería de shell.
fuente
fuente