Dans un script Bash, Comment puis-je quitter le script entier si une certaine condition se produit?
j'écris un script à Bash pour tester du code. Cependant, il semble stupide d'exécuter les tests si compiler le code échoue en premier lieu, auquel cas je vais juste annuler les tests.
y a-t-il un moyen pour que je puisse faire cela sans envelopper le script entier dans une boucle while et en utilisant des pauses? Quelque chose comme un dun dun dun goto?
6 réponses
essayez cette déclaration:
exit 1
remplacer 1
par les codes d'erreur appropriés. Voir aussi codes de sortie ayant une signification spéciale .
Utiliser e
#!/bin/bash
set -e
/bin/command-that-fails
/bin/command-that-fails2
le script se terminera après la première ligne qui échoue (renvoie un code de sortie non nul). Dans ce cas, commande-qui-fails2 ne sera pas exécuté.
si vous deviez vérifier le statut de retour de chaque commande, votre script ressemblerait à ceci:
#!/bin/bash
# I'm assuming you're using make
cd /project-dir
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
cd /project-dir2
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
Avec e , il devrait ressembler à:
#!/bin/bash
set -e
cd /project-dir
make
cd /project-dir2
make
toute commande qui échoue fera échouer le script entier et retournera un statut de sortie que vous pouvez vérifier avec $? . Si votre script est très long ou que vous construisez beaucoup de choses, il va devenir assez laid si vous ajoutez des contrôles de statut de retour partout.
un type des SysOps à gros cul m'a appris une fois la technique de la griffe à trois doigts:
yell() { echo ""151900920": $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
Ces fonctions sont les systèmes unix et le shell saveur robuste. Mettez - les au début de votre script (bash ou autre), try()
votre déclaration et votre code.
explication
(à base de voler des moutons commentaire).
-
yell
: imprimer le script nom et tous les arguments àstderr
:-
"151940920"
est le chemin vers le script; -
$*
sont tous des arguments. -
>&2
signifie>
rediriger stdout vers & pipe2
. pipe1
seraitstdout
elle-même.
-
-
die
fait la même chose queyell
, mais les sorties avec un statut de sortie non 0 , qui signifie"échec". -
try
utilise le||
(booléenOR
), qui évalue seulement le côté droit si le côté gauche n'a pas échoué.-
$@
est de nouveau tous les arguments, mais différent .
-
l'Espérance qui explique tout.
si vous invoquez le script avec source
, vous pouvez utiliser return <x>
où <x>
sera le statut de sortie du script (utilisez une valeur non nulle pour erreur ou false). Cela fonctionnera également comme prévu, lorsque vous source
le script. Si vous invoquez un script exécutable (c'est-à-dire directement avec son nom de fichier), l'instruction return donnera lieu à une plainte (message d'erreur "return: can only `return' from a function or sourced script").
si exit <x>
est utilisé à la place, lorsque le script est invoqué avec source
, il aura pour résultat de quitter le shell qui a démarré le script, mais un script exécutable s'exécutera directement très bien.
pour traiter l'un ou l'autre cas dans le même script, vous pouvez utiliser
return <x> 2> /dev/null || exit <x>
ceci traitera l'invocation qui peut être appropriée.
Note: <x>
est supposé être juste un nombre.
j'inclus souvent une fonction appelée run() pour gérer les erreurs. Chaque appel que je veux faire est passé à cette fonction de sorte que le script entier sort quand un échec est frappé. L'avantage de ceci par rapport à la solution set-e est que le script ne sort pas silencieusement quand une ligne échoue, et peut vous dire quel est le problème. Dans l'exemple suivant, la 3ème ligne n'est pas exécutée parce que le script sort à l'appel à false.
function run() {
cmd_output=$(eval )
return_value=$?
if [ $return_value != 0 ]; then
echo "Command failed"
exit -1
else
echo "output: $cmd_output"
echo "Command succeeded."
fi
return $return_value
}
run "date"
run "false"
run "date"
au lieu de if
construire, vous pouvez tirer parti de la évaluation de court-circuit :
#!/usr/bin/env bash
echo $[1+1]
echo $[2/0] # division by 0 but execution of script proceeds
echo $[3+1]
(echo $[4/0]) || exit $? # script halted with code 1 returned from `echo`
echo $[5+1]
noter la paire de parenthèses qui est nécessaire en raison de la priorité de l'opérateur d'alternance. $?
est une variable spéciale définie pour le code de sortie de la commande la plus récente appelée.