trap script example bash interrupt-handling

bash - trap command in shell script example



Cómo atrapar ERR cuando se usa ''set-e'' en Bash (3)

Reemplace ERR con EXIT y funcionará.

La sintaxis del comando trap es: trap [COMMANDS] [SIGNALS]

Para obtener más información, lea http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html

Tengo un script simple:

#!/bin/bash set -e trap "echo BOO!" ERR function func(){ ls /root/ } func

Me gustaría interceptar ERR si mi script falla (como ocurrirá aquí b / c No tengo los permisos para buscar / root). Sin embargo, cuando se usa set -e no queda atrapado. Sin set -e ERR queda atrapado.

De acuerdo con la página de manual de bash, para set -e :

... Una captura en ERR, si está establecida, se ejecuta antes de que el shell salga. ...

¿Por qué no se ejecuta mi trampa? Desde la página del manual parece que debería.


set -o errtrace usar set -o errtrace para que la función herede la captura.


La respuesta de Chepner es la mejor solución : si desea combinar set -e (igual que: set -o errexit ) con una captura ERR , use también set -o errtrace (igual que: set -E ) .

En resumen: use set -eE en lugar de simplemente set -e :

#!/bin/bash set -eE # same as: `set -o errexit -o errtrace` trap "echo BOO!" ERR function func(){ ls /root/ } func

man bash dice acerca de set -o errtrace / set -E :

Si se establece, cualquier captura en ERR es heredada por funciones de shell, sustituciones de comandos y comandos ejecutados en un entorno de subshell. La trampa ERR normalmente no se hereda en tales casos.

Lo que creo que está sucediendo:

  • Sin -e : el comando ls falla dentro de su función y, debido a ser el último comando en la función, la función reporta el código de salida no nulo de ls a la persona que llama, su alcance de script de nivel superior. En ese ámbito , la captura ERR está en efecto y se invoca (pero tenga en cuenta que la ejecución continuará, a menos que llame explícitamente a exit desde la captura).

  • Con -e (pero sin -E ): el comando ls falla dentro de su función , y debido a que set -e está en efecto, Bash sale instantáneamente , directamente desde el alcance de la función , y como no hay ninguna trampa ERR en efecto allí (porque no se heredó del ámbito principal), su trampa no se llama.

Si bien la página de man no es incorrecta, estoy de acuerdo en que este comportamiento no es exactamente obvio, hay que deducirlo.