Ce script ne fait pas écho "après":
#!/bin/bash -e
echo "before"
echo "anything" | grep e # it would if I searched for 'y' instead
echo "after"
exit
Il en serait de même si je supprimais le -e
option sur la ligne Shebang, mais je souhaite la conserver pour que mon script s'arrête en cas d'erreur. Je ne considère pas que grep ne trouve aucune correspondance comme une erreur. Comment puis-je l'empêcher de sortir si brusquement?
echo "anything" | grep e || true
Explication:
$ echo "anything" | grep e
### error
$ echo $?
1
$ echo "anything" | grep e || true
### no error
$ echo $?
0
### DopeGhoti's "no-op" version
### (Potentially avoids spawning a process, if `true` is not a builtin):
$ echo "anything" | grep e || :
### no error
$ echo $?
0
Le "||" signifie "ou". Si la première partie de la commande "échoue" (ce qui signifie "grep e" renvoie un code de sortie non nul), la partie après le "||" est exécuté, réussit et renvoie zéro comme code de sortie (true
renvoie toujours zéro).
Un moyen robuste pour sécuriser et éventuellement grep
messages:
echo something | grep e || [[ $? == 1 ]] ## print 'something', $? is 0
echo something | grep x || [[ $? == 1 ]] ## no output, $? is 0
echo something | grep --wrong-arg e || [[ $? == 1 ]] ## stderr output, $? is 1
Selon manuel posix , le code de sortie 1 signifie qu'aucune ligne n'est sélectionnée et> 1 signifie une erreur.
Une autre option consiste à ajouter une autre commande au pipeline - une qui n'échoue pas:
echo "anything" | grep e | cat
Étant donné que cat
est désormais la dernière commande du pipeline, c'est l'état de sortie de cat
, et non de grep
, qui sera utilisé pour déterminer si le pipeline a échoué ou non.
#!/bin/bash -e
echo "before"
echo "anything" | grep e || : # it would if I searched for 'y' instead
echo "after"
exit
set -e
ou set -o errexit
Quittez immédiatement si un pipeline (qui peut consister en un seul commande simple), un liste ou un commande composée = (voir
Shell GRAMMAR
ci-dessus), quitte avec un état différent de zéro. Le shell ne se ferme pas si la commande qui échoue fait partie de la liste de commandes suivant immédiatement un mot cléwhile
ouuntil
, une partie du test suivant leif
ouElif
mots réservés, partie de toute commande exécutée dans un&&
ou||
liste sauf la commande suivant la dernière&&
ou||
, toute commande dans un pipeline sauf la dernière, ou si la valeur de retour de la commande est inversée avec!
. Si une commande composée autre qu'un sous-shell renvoie un état différent de zéro car une commande a échoué pendant que-e
était ignoré, le shell ne se ferme pas. Une interruption surERR
, si elle est définie, est exécutée avant la fermeture du shell. Cette option s'applique à l'environnement Shell et à chaque environnement sous-Shell séparément (voirCOMMAND EXECUTION ENVIRONMENT
ci-dessus) et peut entraîner la fermeture des sous-coquilles avant d'exécuter toutes les commandes de la sous-coquille.
De plus, :
est la commande sans effet dans Bash.
Une autre option:
...
set +e
echo "anything" | grep e
set -e
...