-e délenche l'arrêt du script en cas d'erreur non gérée. Cela évite l'effet boule de neige où une erreur d'un script déclenche une avalanche d'erreur dans les commandes suivantes du script. Avec -e, bash s'arrête et affiche l'erreur à l'origine de toute la catastrophe qui aurait put se passer ensuite.
-u change le comportement de bash en regard des variables indéfinie. Par défaut, une variable indéfinie est substituée par la chaîne vide. Avec -u, bash lève une erreur et arrête le script. Cela évite notamment les erreurs avec le typo dans un nom de variable.
-eu est en quelque sorte le mode strict de bash, pour reprendre une terminologie de PHP. Autant, en interactif, -eu sont inutilisables, autant dans un scripts ils me semblent indispensables.
Notons cependant qu'ils peuvent être inutilisables en script. Dès qu'on commence à faire des trucs un peu complexes, ça peut vite péter. J'ai quelques scripts qui supportent pas -e (ça pète pour rien).
Pour une suite de commandes à la makefile, ça se tiens, mais sinon c'pas toujours possible. Activer/désactiver les options au besoin à coup de set est intéressant et éviter de couper l'exécution durant un traitement correct.
Heu… non, certainement pas. Ça sert à « inverser » le code de retour, l'effet d'ignorer les erreurs qui suivent n'est qu'un effet de bord. Et ça rends inexploitable le code de retour de la commande (sauf à vouloir explicitement inverser le résultat).
Autant adapter ses scripts à son usage, je veux bien, autant utiliser des bricolages du langage, bof. Sans parler de la lisibilité qui en prends un coup…
Personnellement, je préfère traiter les erreurs (pré-vérifications, récupérations des codes d'erreurs et/ou de la sortie pour déterminer les actions à faire, etc) plutôt que d'activer un réglage Bash qui pourrait me mettre des bâtons dans les roues (en ne catchant pas certains cas que je considère comme erreur malgré le code 0, ou en catchant des cas que je ne trouve pas anormaux malgré le code de retour > 0).
Il m'arrive d'utiliser -e, mais généralement je l'active que quand j'ai tout un bloc de commandes lancées sans conditions à la suite et qui ne sont pas censées foirer. Du coup si ça plante à cet endroit, c'est qu'il y a un cas totalement imprévu.
Au final, ça dépends de la situation, des préférences et habitudes, etc.
As-tu essayé le bout de script que j'ai partagé ? ! true n'arrête pas le script. C'est à dire que -e ignore le retour de !, quelque soit le résultat de la commande. En début de commande, ! est en bash comme le - de GNU Make. C'est un autre usage de !.
Toute erreur non gérée doit être une rédhibitoire.
Ah mais j'ai pas dis le contraire. Je dis juste que ! true retourne 1. Même s'il arrête pas le script, ça fausse le code de sortie. ! sert avant tout à inverser le code de retour, pas à l'ignorer. Ça c'est qu'un effet de bord.
Quant à -u, ça permet d'éviter pas mal d'arrachages de cheveux. Perso je teste systématiquement à coup de test -z ou test -n les variables qui doivent absolument ne pas être vides (et j'ai aussi des cas de variables légitimement vides).
Après, mettre -eu par défaut et ne le virer que quand on a besoin (avec set par exemple), c'est plutôt une bonne idée, surtout si on a pas l'habitude de certains comportements de Bash (qui varient de ce qu'on trouve ailleurs).
Bref, question d'habitude, chacun fait ce qu'il veut, tant que c'est en connaissance de cause.
Exactement, il m'arrive d'encadrer du code pas fiable avec set +eu; ...; set -eu dans le pire des cas. C'est très rare dans mon expérience.
Je trouve que les if $? ... sont très verbeux. Pire, j'ai vu un collègue écrire des script avec && à la fin de chaque ligne. -e rends les scripts plus lisible à mon goût.
Mettez
#!/bin/bash -eu
et sauvez un chaton d'une mort effroyable !Une petite explication du pourquoi ?
-e
délenche l'arrêt du script en cas d'erreur non gérée. Cela évite l'effet boule de neige où une erreur d'un script déclenche une avalanche d'erreur dans les commandes suivantes du script. Avec-e
, bash s'arrête et affiche l'erreur à l'origine de toute la catastrophe qui aurait put se passer ensuite.-u
change le comportement de bash en regard des variables indéfinie. Par défaut, une variable indéfinie est substituée par la chaîne vide. Avec-u
, bash lève une erreur et arrête le script. Cela évite notamment les erreurs avec le typo dans un nom de variable.-eu
est en quelque sorte le mode strict de bash, pour reprendre une terminologie de PHP. Autant, en interactif,-eu
sont inutilisables, autant dans un scripts ils me semblent indispensables.Merci pour l'explication complète :)
Notons cependant qu'ils peuvent être inutilisables en script. Dès qu'on commence à faire des trucs un peu complexes, ça peut vite péter. J'ai quelques scripts qui supportent pas
-e
(ça pète pour rien).Pour une suite de commandes à la makefile, ça se tiens, mais sinon c'pas toujours possible. Activer/désactiver les options au besoin à coup de set est intéressant et éviter de couper l'exécution durant un traitement correct.
Mieux vaut ignorer explicitement les erreurs.
!
joue ce rôle.Heu… non, certainement pas. Ça sert à « inverser » le code de retour, l'effet d'ignorer les erreurs qui suivent n'est qu'un effet de bord. Et ça rends inexploitable le code de retour de la commande (sauf à vouloir explicitement inverser le résultat).
Autant adapter ses scripts à son usage, je veux bien, autant utiliser des bricolages du langage, bof. Sans parler de la lisibilité qui en prends un coup…
Personnellement, je préfère traiter les erreurs (pré-vérifications, récupérations des codes d'erreurs et/ou de la sortie pour déterminer les actions à faire, etc) plutôt que d'activer un réglage Bash qui pourrait me mettre des bâtons dans les roues (en ne catchant pas certains cas que je considère comme erreur malgré le code 0, ou en catchant des cas que je ne trouve pas anormaux malgré le code de retour > 0).
Il m'arrive d'utiliser
-e
, mais généralement je l'active que quand j'ai tout un bloc de commandes lancées sans conditions à la suite et qui ne sont pas censées foirer. Du coup si ça plante à cet endroit, c'est qu'il y a un cas totalement imprévu.Au final, ça dépends de la situation, des préférences et habitudes, etc.
As-tu essayé le bout de script que j'ai partagé ?
! true
n'arrête pas le script. C'est à dire que-e
ignore le retour de!
, quelque soit le résultat de la commande. En début de commande,!
est en bash comme le-
de GNU Make. C'est un autre usage de!
.Toute erreur non gérée doit être une rédhibitoire.
Ah mais j'ai pas dis le contraire. Je dis juste que
! true
retourne 1. Même s'il arrête pas le script, ça fausse le code de sortie.!
sert avant tout à inverser le code de retour, pas à l'ignorer. Ça c'est qu'un effet de bord.Quant à
-u
, ça permet d'éviter pas mal d'arrachages de cheveux. Perso je teste systématiquement à coup detest -z
outest -n
les variables qui doivent absolument ne pas être vides (et j'ai aussi des cas de variables légitimement vides).Après, mettre
-eu
par défaut et ne le virer que quand on a besoin (avecset
par exemple), c'est plutôt une bonne idée, surtout si on a pas l'habitude de certains comportements de Bash (qui varient de ce qu'on trouve ailleurs).Bref, question d'habitude, chacun fait ce qu'il veut, tant que c'est en connaissance de cause.
Exactement, il m'arrive d'encadrer du code pas fiable avec
set +eu; ...; set -eu
dans le pire des cas. C'est très rare dans mon expérience.Je trouve que les
if $? ...
sont très verbeux. Pire, j'ai vu un collègue écrire des script avec&&
à la fin de chaque ligne.-e
rends les scripts plus lisible à mon goût.