J'ai un script shell Bash qui appelle un certain nombre de commandes. Je voudrais que le script shell se termine automatiquement avec une valeur de retour de 1 si l'une des commandes renvoie une valeur non nulle.
Est-ce possible sans vérifier explicitement le résultat de chaque commande?
par exemple
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
set -e
, faites égalementset -u
(ouset -eu
).-u
met fin au comportement idiot de masquage de bogues auquel vous pouvez accéder à n'importe quelle variable inexistante et produire une valeur vide sans diagnostic.Réponses:
Ajoutez ceci au début du script:
Cela provoquera la fermeture immédiate du shell si une simple commande se termine avec une valeur de sortie différente de zéro. Une commande simple est une commande ne faisant pas partie d'un test if, while ou until, ou faisant partie d'un && ou || liste.
Voir la page de manuel bash (1) sur la commande interne "set" pour plus de détails.
Personnellement, je démarre presque tous les scripts shell avec "set -e". C'est vraiment ennuyeux de voir un script continuer obstinément quand quelque chose échoue au milieu et casse les hypothèses pour le reste du script.
la source
bash script.sh
.set -e; tf() { false; }; tf; echo 'still here'
. Même sans l'set -e
intérieur du corps detf()
, l'exécution est interrompue. Peut-être vouliez-vous dire que ceset -e
n'est pas hérité des sous - coquilles , ce qui est vrai.Pour ajouter à la réponse acceptée:
Gardez à l'esprit que
set -e
parfois cela ne suffit pas, surtout si vous avez des tuyaux.Par exemple, supposons que vous ayez ce script
... qui fonctionne comme prévu: une erreur dans
configure
abandonne l'exécution.Demain, vous effectuez un changement apparemment insignifiant:
... et maintenant ça ne marche pas. Ceci est expliqué ici et une solution de contournement (Bash uniquement) est fournie:
la source
pipefail
accepterset -o
!Les instructions if de votre exemple ne sont pas nécessaires. Faites comme ça:
Si vous suivez les conseils de Ville Laurikari et utilisez
set -e
alors pour certaines commandes, vous devrez peut-être utiliser ceci:Le
|| true
fera que le pipeline de commandes aura unetrue
valeur de retour même si la commande échoue, donc l'-e
option ne tuera pas le script.la source
set -e
n'est pas centré sur bash - il est pris en charge même sur le Bourne Shell d'origine.Si vous avez un nettoyage à faire à la sortie, vous pouvez également utiliser «trap» avec le pseudo-signal ERR. Cela fonctionne de la même manière que le piégeage INT ou tout autre signal; bash lance ERR si une commande se termine avec une valeur différente de zéro:
Ou, surtout si vous utilisez "set -e", vous pouvez intercepter EXIT; votre piège sera alors exécuté lorsque le script se fermera pour une raison quelconque, y compris une fin normale, des interruptions, une sortie provoquée par l'option -e, etc.
la source
La
$?
variable est rarement nécessaire. Le pseudo-idiomecommand; if [ $? -eq 0 ]; then X; fi
doit toujours s'écrireif command; then X; fi
.Les cas où cela
$?
est requis, c'est quand il doit être comparé à plusieurs valeurs:ou lorsqu'il
$?
doit être réutilisé ou manipulé d'une autre manière:la source
Exécutez-le avec
-e
ouset -e
en haut.Regardez aussi
set -u
.la source
help set
:-u
traite les références aux variables non définies comme des erreurs.set -u
ouset -e
pas les deux? @lumpynoseUne expression comme
arrêtera le traitement lorsque l'une des commandes reviendra avec une valeur non nulle. Par exemple, la commande suivante n'imprimera jamais "terminé":
la source
devrait suffire.
la source
j'en ai juste ajouté un autre à titre de référence car il y avait une question supplémentaire à l'entrée de Mark Edgars et voici un exemple supplémentaire et touche le sujet dans son ensemble:
ce qui est le même que celui
cmd || exit errcode
que quelqu'un a montré.par exemple. Je veux m'assurer qu'une partition est démontée si elle est montée:
la source
[[
cmd`]] `n'est pas la même chose. C'est faux si la sortie de la commande est vide et vrai sinon, quel que soit l'état de sortie de la commande.