J'utilise set -e
pour arrêter le script bash lors de la première erreur .
Tout fonctionne correctement sauf si j'utilise la command avec &&
:
$ cat script set -e cd not_existing_dir && echo 123 echo "I'm running! =P" $ $ ./script ./script: line 2: cd: not_existing_dir: No such file or directory I'm running! =P $
comparé à:
$ cat script set -e cd not_existing_dir echo "I'm running! =P" $ $ ./script ./script: line 2: cd: not_existing_dir: No such file or directory $
Le premier exemple I'm running!
fait toujours écho I'm running!
, mais le second ne le fait pas. Pourquoi se comportent-ils différemment?
UPD. Question similaire: https://stackoverflow.com/questions/6930295/set-e-and-short-tests
C'est un comportement documenté. La page de manuel bash (1) dit, pour set -e
,
Le shell ne quitte pas si la command qui échoue fait partie de la list de commands immédiatement après un
while
ouuntil
mot key, partie du test suivant les mots réservéselif
ouelif
, fasse partie d'une command exécutée dans un&&
ou||
list sauf la command qui suit le&&
ou||
, n'importe quelle command dans un pipeline mais la dernière, ou si la valeur de return de la command est inversée avec!
.
[Je souligne.]
Et la spécification du langage de command du shell POSIX confirme que c'est le comportement correct:
Le paramètre
-e
doit être ignoré lors de l'exécution de la list composée après le motwhile
,if
, ouelif
reserved, un pipeline commençant par le!
mot réservé, ou toute command d'une list AND-OR autre que le dernier.
et la section 2.9.3, les lists de ce document définissent
Une list AND-OR est une séquence d'un ou plusieurs pipelines séparés par les opérateurs "
&&
" et "||
".
L'option set -e
n'a pas d'effet dans certaines situations, et il s'agit du comportement standard et portable à travers le shell compatible POSIX.
La command ayant échoué fait partie du pipeline:
false | true; echo printed
imprimera printed
.
Et seul l'échec du pipeline lui-même est considéré:
true | false; echo 'not printed'
n'imprimera rien.
La command échouée s'exécute dans la list composée après le while
, until
, if
, elif
mot réservé, un pipeline commençant par le !
mot réservé, ou toute command dans le cadre de &&
ou ||
list sauf la dernière:
false || true; echo printed
La dernière command échoue set -e
: set -e
affected:
true && false; echo 'not printed'
Le sous-shell échoue dans une command composée:
(false; echo 'not printed') | cat -; echo printed
ma conjecture est si-alors la condition dans son set évaluer à vrai.
j'ai essayé
set -e if cd not_existing_dir then echo 123 fi echo "I'm running! =P"
qui donne
-bash: cd: not_existing_dir: No such file or directory I'm running! =P
le code d'erreur est intercepté par condition si, bash ne triggersra pas la fin de l'exécution.