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
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 $? )&
set -e
. Cela ne sapplique cependant pas ' ici. LOP souhaite quitter le script après 5 tentatives infructueuses dexécution de la commande.set -e
est le seul moyen que je connaisse pour le faire.set -e
issleep
(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 dansif
ou à gauche de&&
ne sont pas affectés parset -e
,n=...
pourrait échouer sin
est en lecture seule, mais alors cela quitterait le script sansset -e
également), de sorte que linterprétation semble assez improbable. Je reconnais que la question est mal formulée.