la ERR
trampa no es ejecutar código cuando el shell mismo sale con un código de error distinto de cero, sino cuando cualquier comando ejecutado por ese shell que no es parte de una condición (como en if cmd...
, o cmd || ...
...) sale con un código distinto de cero estado de salida (las mismas condiciones que lo que hace set -e
que salga del shell).
Si desea ejecutar código al salir del shell con un estado de salida distinto de cero, debe agregar una trampa en su EXIT
lugar y verificar $?
allí:
trap '[ "$?" -eq 0 ] || echo hi' EXIT
Sin embargo, tenga en cuenta que en una señal atrapada, se ejecutarán tanto la captura de señal como la captura EXIT, por lo que es posible que desee hacerlo como:
unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
ret=$?
if [ -n "$killed_by" ]; then
echo >&2 "Ouch! Killed by $killed_by"
exit 1
elif [ "$ret" -ne 0 ]; then
echo >&2 "Died with error code $ret"
fi' EXIT
O para usar el estado de salida como $((signum + 128))
en las señales:
for sig in INT TERM HUP; do
trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
ret=$?
[ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT
Sin embargo, tenga en cuenta que salir normalmente de SIGINT o SIGQUIT tiene posibles efectos secundarios molestos cuando su proceso principal es un shell como el bash
que implementa el manejo de espera y salida cooperativa de la interrupción de terminal. Por lo tanto, es posible que desee asegurarse de suicidarse con la misma señal para informar a sus padres que realmente fue interrumpido, y que debería considerar salir también si recibió un SIGINT / SIGQUIT.
unset killed_by
for sig in INT QUIT TERM HUP; do
trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
ret=$?
[ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
if [ -n "$killed_by" ]; then
trap - "$killed_by" # reset handler
# ulimit -c 0 # possibly disable core dumps
kill -s "$killed_by" "$$"
else
exec "$ret"
fi' EXIT
Si desea ERR
que se dispare la trampa, simplemente ejecute un comando con un estado de salida distinto de cero como false
o test
.