le ERR
piège n'est pas d'exécuter du code lorsque le shell lui-même se termine avec un code d'erreur non nul, mais lorsqu'une commande exécutée par ce shell qui ne fait pas partie d'une condition (comme dans if cmd...
, ou cmd || ...
...) se termine avec un non nul état de sortie (les mêmes conditions que celles qui provoquent la set -e
sortie du shell).
Si vous souhaitez exécuter du code à la sortie du shell avec un état de sortie différent de zéro, vous devez ajouter un piège à la EXIT
place et $?
y vérifier :
trap '[ "$?" -eq 0 ] || echo hi' EXIT
Notez cependant que lors d'un signal piégé, le piège de signal et le piège EXIT seraient exécutés, vous pouvez donc le faire comme suit:
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
Ou pour utiliser l'état de sortie comme $((signum + 128))
sur les signaux:
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
Notez cependant que quitter normalement sur SIGINT ou SIGQUIT a des effets secondaires potentiellement gênants lorsque votre processus parent est un shell comme bash
celui qui implémente l' attente et la gestion coopérative des sorties d'interruption de terminal. Donc, vous voudrez peut-être vous assurer de vous tuer avec le même signal à la place afin de signaler à votre parent que vous avez bien été interrompu et qu'il devrait également envisager de se quitter s'il a reçu 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 vous voulez que le ERR
piège se déclenche, exécutez simplement une commande avec un état de sortie différent de zéro comme false
ou test
.
Stéphane Chazelas
la source