Considérez cet extrait:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Normalement, quand func
est appelé, le script se terminera, ce qui est le comportement souhaité. Cependant, s'il est exécuté dans un sous-shell, comme dans
result=`func`
il ne quittera pas le script. Cela signifie que le code appelant doit vérifier à chaque fois l'état de sortie de la fonction. Y a-t-il un moyen d'éviter cela? C'est pour ça set -e
?
shell
shell-script
exit
subshell
Ernest AC
la source
la source
func
.Réponses:
Vous pourriez tuer le shell d'origine (
kill $$
) avant d'appelerexit
, et cela fonctionnerait probablement. Mais:Au lieu de cela, vous pouvez utiliser l'une des nombreuses façons de renvoyer une valeur dans la FAQ Bash . La plupart d'entre eux ne sont pas si grands, malheureusement. Vous pouvez simplement être bloqué à la recherche d'erreurs après chaque appel de fonction (
-e
a beaucoup de problèmes ). Soit cela, soit basculez vers Perl.la source
Vous pouvez décider que le statut de sortie 77, par exemple, signifie quitter n'importe quel niveau de sous-shell, et faire
set -E
en combinaison avec desERR
pièges est un peu comme une version améliorée deset -e
en ce qu'elle vous permet de définir votre propre gestion des erreurs.Dans zsh, les interruptions ERR sont héritées automatiquement, vous n'avez donc pas besoin
set -E
, vous pouvez également définir des interruptions en tant queTRAPERR()
fonctions et les modifier$functions[TRAPERR]
, commefunctions[TRAPERR]="echo was here; $functions[TRAPERR]"
la source
kill $$
.echo "$(exit 77)"
; le script continuera comme si nous avions écritecho ""
Comme alternative à
kill $$
, vous pouvez également essayerkill 0
, cela fonctionnera dans le cas de sous-coquilles imbriquées (tous les appelants et processus secondaires recevront le signal)… mais c'est toujours brutal et laid.la source
Essaye ça ...
Les résultats que j'obtiens sont ...
Remarques
if
test d'êtretrue
oufalse
(voir les 2 runs)if
test est terminéfalse
, nous n'atteignons jamais le sous-shell.la source
(Réponse spécifique à Bash) Bash n'a aucun concept d'exceptions. Cependant, avec set -o errexit (ou l'équivalent: set -e) au niveau le plus externe, la commande ayant échoué entraînera la sortie du sous-shell avec un état de sortie non nul. S'il s'agit d'un ensemble de sous-coquilles imbriquées sans condition autour de l'exécution de ces sous-coquilles, il «enroulera» efficacement le script entier et quittera.
Cela peut être difficile lorsque vous essayez d'inclure des bits de divers codes bash dans un script plus grand. Un morceau de bash peut très bien fonctionner seul, mais lorsqu'il est exécuté sous errexit (ou sans errexit), se comporte de manière inattendue.
la source
Mon exemple pour sortir dans une doublure:
la source