Comment quitter un script shell si une partie de celui-ci échoue?

Comment puis-je écrire un script shell qui se termine, si une partie échoue? Par exemple, si lextrait de code suivant échoue, le script doit se fermer.

n=0 until [ $n -ge 5 ] do gksu *command* && break n=$[$n+1] sleep 3 

Answer

Une approche serait dajouter set -e au début de votre script. Cela signifie (de help set):

 -e Exit immediately if a command exits with a non-zero status. 

Donc, si lune de vos commandes échoue, le script se fermera.

Vous pouvez également ajouter des instructions exit explicites aux points déchec possibles:

command || exit 1 

Commentaires

  • Je (et le wiki bash ) préféreraient que les gens réfléchissent à la bonne gestion des erreurs plutôt que dutiliser la fonction (interrompue par la conception IMO) set -e. Cela ne sapplique cependant pas ' ici. LOP souhaite quitter le script après 5 tentatives infructueuses dexécution de la commande.
  • @St é phaneChazelas Jai gagné ' t discuter avec vous pour savoir si ' est cassé, je ' suis sûr que vous ' re droite. Cependant, lOP a demandé " Comment puis-je écrire un script shell qui se termine, si une partie échoue? ", quest-ce qui vous rend pensez-vous ' de quitter après 5 échecs?
  • parce que je ne peux ' penser à aucune autre façon question peut être interprétée.
  • @St é phaneChazelas vous avez peut-être raison. Je lai interprété littéralement: comment tout le script peut-il se terminer si une partie de celui-ci échoue. Et set -e est le seul moyen que je connaisse pour le faire.
  • Dans cet extrait de script, les commandes qui pourraient déclencher set -e is sleep (break étant une fonction intégrée spéciale entraînerait la fermeture du script en cas déchec dans la plupart des shells, les commandes dans if ou à gauche de && ne sont pas affectés par set -e, n=... pourrait échouer si n est en lecture seule, mais alors cela quitterait le script sans set -e également), de sorte que linterprétation semble assez improbable. Je reconnais que la question est mal formulée.

Réponse

Vous pouvez quitter un script à tout endroit en utilisant le mot-clé exit. Vous pouvez également spécifier un code de sortie afin dindiquer à dautres programmes que ou comment votre script a échoué, par exemple exit 1 ou exit 2 etc. (Par convention, le code de sortie 0 signifie le succès et tout ce qui est supérieur à 0 signifie un échec; cependant, également par convention , les codes de sortie supérieurs à 127 sont réservés pour une terminaison anormale (par exemple par un signal)).

La construction générique pour quitter en cas déchec est

if [ failure condition ]; then exit n fi 

avec failure condition et n appropriés. Mais dans des scénarios spécifiques, vous pouvez procéder différemment. Maintenant, pour votre cas, jinterprète votre question que si lune des cinq invocations de gksu échoue, alors vous voulez quitter. Une façon est dutiliser une fonction comme celle-ci

function try_command { for i in 1 2 3 4 5 ; do if gksu command ; then return 0 fi fi exit 1 } 

et ensuite, dappeler la boucle par try_command.

Il existe des moyens (plus) avancés ou sophistiqués de répondre à votre question. Cependant, la solution ci-dessus est plus accessible aux débutants que, par exemple, la solution de Stéphane.

Réponse

attempt=0 until gksu command; do attempt=$((attempt + 1)) if [ "$attempt" -gt 5 ]; then exit 1 fi done 

exit quitte le script à moins quil ne soit appelé dans un sous-shell. Si cette partie du script se trouve dans un sous-shell, par exemple parce quelle « est dans (...) ou $(...) ou fait partie dun pipe-line , alors il ne quittera que ce sous-shell .

Dans ce cas, si vous voulez que le script se termine en plus du sous-shell, alors vous  » Vous devrez appeler exit à la sortie de ce sous-shell.

Par exemple, ici avec 2 niveaux imbriqués de sous-shell:

( life=hard output=$( echo blah [ "$life" = easy ] || exit 1 # exit subshell echo blih not run ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status echo not run either ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status 

Cela peut devenir plus délicat si le sous-shell fait partie dun pipeline. bash a un tableau $PIPESTATUS spécial, similaire à zsh « s $pipestatus celui qui peut vous aider ici:

{ echo foo exit 1 echo bar } | wc -c subshell_ret=${PIPESTATUS[0]} if [ "$subshell_ret" -ne 0 ]; then exit "$subshell_ret" fi 

Réponse

Trap effectuera une action à la réception dun signal.

trap "echo EXIT; exit" 0 trap "echo HUP; exit" 1 trap "echo CTL-C; exit" 2 trap "echo QUIT; exit" 3 trap "echo ERR; exit" ERR n=0 until [ $n -ge 5 ] do n=$[$n+1] echo $n sleep 3 done 

Exécutez ceci et laissez-le sortir normalement. Il intercepte sur le signal 0.

EXIT 

Exécutez-le à nouveau et interrompez avec ^ C. Il intercepte à la fois le signal 2 et le signal 0.

CTL-C EXIT 

Un statut de sortie différent de zéro piège sur ERR

ERR EXIT 

Réponse

pass_to_functio() { echo "command exited with status $1" } ( exec <Any Command > & child_pid=$! wait $child_pid pass_to_function $? )& 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *