J'ai un script simple:
#!/bin/bash
set -e
trap "echo BOO!" ERR
function func(){
ls /root/
}
func
Je voudrais piéger ERR si mon script échoue (car il sera ici b/c, je n'ai pas les autorisations pour regarder dans/root). Cependant, lorsque vous utilisez set -e
il n'est pas piégé. Sans pour autant set -e
ERR est piégé.
Selon la page de manuel de bash, pour set -e
:
... Un piège sur ERR, s'il est défini, est exécuté avant la fermeture du shell. ...
Pourquoi mon piège n'est-il pas exécuté? De la page de manuel, il semble que cela devrait.
réponse de chepner est la meilleure solution : si vous voulez combiner set -e
(pareil que: set -o errexit
) avec un piège ERR
, utilisez également set -o errtrace
(pareil que: set -E
) .
En bref: utilisez set -eE
au lieu de simplement set -e
:
#!/bin/bash
set -eE # same as: `set -o errexit -o errtrace`
trap 'echo BOO!' ERR
function func(){
ls /root/
}
# Thanks to -E / -o errtrace, this still triggers the trap,
# even though the failure occurs *inside the function*.
func
man bash
dit à propos de set -o errtrace
/set -E
:
S'il est défini, tout piège sur ERR est hérité par les fonctions Shell, les substitutions de commandes et les commandes exécutées dans un environnement de sous-shell. Le piège ERR n'est normalement pas hérité dans de tels cas.
Je crois que ce qui se passe:
Sans-e
: La commande ls
échoue à l'intérieur de votre fonction et, en raison de sa dernière commande, la fonction signale le code de sortie non nul de ls
à l'appelant, la portée de votre script de niveau supérieur . Dans cette étendue, l'interruption ERR
est en vigueur et elle est invoquée (mais notez que l'exécution continuera, sauf si vous appelez explicitement exit
à partir de l'interruption ).
Avec-e
(mais sans -E
): La commande ls
échoue à l'intérieur de votre fonction, et parce que set -e
est en vigueur, Bash instantanément se termine, directement depuis la portée de la fonction - et puisqu'il n'y a pas de ERR
trap en vigueur ici (car il n'a pas été hérité de la portée parent), votre trap n'est pas appelé.
Bien que la page man
ne soit pas incorrecte, je conviens que ce comportement n'est pas exactement évident - vous devez le déduire.
Vous devez utiliser set -o errtrace
pour que la fonction hérite du piège.
Remplacez ERR
par EXIT
et cela fonctionnera.
La syntaxe de la commande trap
est: trap [COMMANDS] [SIGNALS]
Pour plus d'informations, veuillez lire http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html