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 comandols
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 dels
a la persona que llama, su alcance de script de nivel superior. En ese ámbito , la capturaERR
está en efecto y se invoca (pero tenga en cuenta que la ejecución continuará, a menos que llame explícitamente aexit
desde la captura).Con
-e
(pero sin-E
): el comandols
falla dentro de su función , y debido a queset -e
está en efecto, Bash sale instantáneamente , directamente desde el alcance de la función , y como no hay ninguna trampaERR
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.