J'ai un script shell avec des boucles imbriquées et je viens de découvrir que "exit" ne quitte pas vraiment le script, mais seulement la boucle actuelle. Existe-t-il un autre moyen de quitter complètement le script dans une certaine condition d'erreur?
Je ne veux pas utiliser "set -e", car il y a des erreurs acceptables et cela nécessiterait trop de réécriture.
En ce moment, j'utilise kill pour tuer manuellement le processus, mais il semble qu'il devrait y avoir une meilleure façon de le faire.
bash -c 'for x in y z; do exit; done; echo "This never gets printed"'
.Réponses:
Votre problème n'est pas les boucles imbriquées en soi. C'est qu'une ou plusieurs de vos boucles internes s'exécutent dans un sous-shell .
Cela marche:
production:
Cela présente le problème que vous avez décrit:
production:
Voici la solution; vous devez tester la valeur de retour des boucles internes qui s'exécutent en sous-shell:
Notez le test:
[[ $? != 0 ]] && exit $?
production:
Modifier: pour vérifier dans quel sous-shell vous vous trouvez, modifiez le script «réponse» pour vous indiquer l'ID de processus de votre shell actuel. REMARQUE: cela ne fonctionne que dans bash 4:
production:
Les variables "i" et "j" vous ont été gracieusement fournies par Fortran. Bonne journée. :-)
la source
bash --version
sur la ligne de commande.Une réponse antérieure suggère d'utiliser
[[ $? != 0 ]] && exit $?
mais cela ne fonctionnera pas tout à fait comme prévu, car le[[ $? != 0 ]]
test sera réinitialisé$?
à zéro, ce qui signifie que bien que le script se termine prématurément comme prévu, il se terminera toujours avec le code 0 (comme cela n'était pas prévu) . En outre, il serait préférable d'utiliser le-ne
test de comparaison numérique plutôt que le!=
test de comparaison de chaînes. Donc, à mon humble avis, une meilleure solution consiste à utiliser:car cela garantira que le code de sortie réel est correctement défini.
la source
Vous pouvez utiliser
break
.De
help break
:Donc, pour sortir de trois boucles englobantes, c'est-à-dire si vous avez deux boucles imbriquées à l'intérieur de la boucle principale, utilisez-la pour quitter chacune d'elles:
la source
for((i=0;i<3;i++));do echo A;for((j=0;j<2;j++));do echo B;break 2;done;done
exit
ne termine pas le shell entier, ou le sous-shell actuel:la source