Apprendre à maîtriser les conditions en bash
Un tutoriel de Quentin Busuttil
Le 2017-11-21 02:24:17, par Buzut, Membre émérite
Chers membres du club,
J'ai le plaisir de vous présenter ce tutoriel de Quentin Busuttil :
Bonne lecture
Retrouvez les meilleurs cours et tutoriels pour apprendre le système Linux.
J'ai le plaisir de vous présenter ce tutoriel de Quentin Busuttil :
Le scripting bash est souvent déroutant. La syntaxe est parfois assez éloignée de ce à quoi nous sommes habitués dans d'autres langages. C'est d'ailleurs pourquoi beaucoup l'évitent au maximum. Pourtant, tôt ou tard, on a tous besoin d'écrire un petit .sh pour gérer un service ou automatiser un comportement sur un serveur.
Voilà pourquoi un petit rappel du fonctionnement des conditions - base de tout langage de programmation - en bash peut s'avérer salvateur. En route pour bashland !
Sous Linux et Unix, il existe plusieurs interpréteurs de commandes ou shells. Les fonctions supportées par l'un ou l'autre peuvent varier. Ainsi, nous parlons ici de bash, alias bourne again shell, une implémentation du shell standard d'Unix, sh, le shell historique. Bash est 100 % compatible avec sh, en revanche, la réciproque n'est pas vraie. Nous verrons justement cela dans les conditions.
Voilà pourquoi un petit rappel du fonctionnement des conditions - base de tout langage de programmation - en bash peut s'avérer salvateur. En route pour bashland !
Sous Linux et Unix, il existe plusieurs interpréteurs de commandes ou shells. Les fonctions supportées par l'un ou l'autre peuvent varier. Ainsi, nous parlons ici de bash, alias bourne again shell, une implémentation du shell standard d'Unix, sh, le shell historique. Bash est 100 % compatible avec sh, en revanche, la réciproque n'est pas vraie. Nous verrons justement cela dans les conditions.
-
disedorgueExpert éminent séniorPour ma part, il y a des lacunes dans les explications, exemple:
Syntaxe invalide mais pas d'erreur:
Code : 1
2$ [ 1=1 ] && echo ok ok
Code : 1
2$ [ 1 = 1 ] && echo ok ok
Il manque aussi les expressions du type:
Code : 1
2
3
4$ [ 1 = 1 -o 2 = 1 ] && echo ok ok $ [ 1 = 1 -a 2 = 2 ] && echo ok ok
Code : 1
2$ if (( 1==1 ? 0 : 1 )) ; then echo ok ; else echo ko ; fi ko
Code : 1
2
3
4$ echo $(( 1==1 ? 5 : 6 )) 5 $ echo $(( 1==0 ? 5 : 6 )) 6
Code : grep -q ":${USER}:" /etc/passwd && echo "$USER existe" || echo "$USER n'existe pas"
Donc la syntaxe simplifier doit sous entendre la syntaxe complète suivante:
Code : grep -q ":${USER}:" /etc/passwd && { echo "$USER existe" ; true ; } || echo "$USER n'existe pas"
le 21/11/2017 à 10:52 -
ok.IdrissRédacteurBonjour.
Je plussoie pour l'imprécision de la phrase "Par ailleurs, on trouvera des crochets en lieu et place des habituelles parenthèses."
Originellement [ est une commande indépendante de l'instruction shell if (il s'agit d'ailleurs d'un fork de la commande test) qui renvoie succès (0) si l'expression booléénne est vrai et échec (1) si l'expression booléénne en paramètre est fausse :Code : 1
2
3
4
5
6ineumann ~ $ [ "u" = "v" ] ineumann ~ $ echo $? 1 ineumann ~ $ [ "u" = "u" ] ineumann ~ $ echo $? 0
Code : 1
2ineumann ~ $ ls -l /bin/[ -rwxr-xr-x. 1 root root 53264 Oct 31 2016 '/bin/['
En outre if lui test le retour d'une commande (si retour 0 alors on rentre dans le if, sinon non de même que pour the_cmd && echo "ok" || echo "ko", syntaxe que vous pourriez aborder d'ailleurs) et donc pas forcemment uniquement [ : if grep, if test, ...
Bref, on a l'habitude de ne pas faire d'approximations ou d'affirmations fausses dans les cours de developpez.com même si les intentions sont louables, cela peux conduire à des erreurs de compréhensions qui peuvent parfois être génantes et à l'origine de bugs.
Je plussoie également pour le fait que sur une communauté de professionnel on évites les phrases comme "ta mère" qui sont à mon sens déplacées dans un cours rédigé à l'usage de professionnels. Dans une formation interne entre collègues et sur des slides à la limite on peu se permettre d'être "fun" à sa manière mais dans un cours ou ouvrage rédigé et pour une grande audience, c'est inapproprié.
En l'état je ne vois pas bien la valeur ajoutée par rapport aux autres cours sur le Shell qui sont déjà présents sur DVP (en particulier celui de Frédéric dans lequel figure tout le contenu de vos explications avec moins d'imprécisions). Par contre si vous détaillez davantage les explications à partir de nos messages, cela pourrait avoit un intérêt.
Bien à vous,
Idrissle 22/11/2017 à 11:59 -
N_BaHModérateurBonjour,
Par ailleurs, on trouvera des crochets en lieu et place des habituelles parenthèses.
d'ailleurs "habituelles" par rapport à quoi ?
la syntaxe de if estCode : if COMMANDES; then COMMANDES; [ elif COMMANDES; then COMMANDES; ]... [ else COMMANDES; ] fi
donc, il est possible d'écrireCode : if grep -q ":${USER}:" /etc/passwd; then echo "$USER est un utilisateur"; else echo "$USER n'est pas un utilisateur"; fi
il vaut mieux ne pas utiliser == avec test pour ne pas confondre le comportement qu'ils ont entre double crochets.
c'est bien de souligner que, lorsqu'on emploi la commande test (ou son synonyme), les variables doivent toujours être mises entre guillemets. si, si, c'est une obligation, sous risque d'erreur; tu l'indiques justement.
ce n'est pas le cas pour les doubles crochets. (voir plus bas)
un simili d'expression régulière
il est possible d'omettre les guillemets autour des variables, car les espaces ne causent plus problème. C'est cependant une bonne habitude à conserver, car ailleurs dans les scripts, il est plus prudent de les mettre.
les conditions simples ne requièrent pas if.
pour reprendre mon exemple précédent :Code : grep -q ":${USER}:" /etc/passwd && echo "$USER existe" || echo "$USER n'existe pas"
le 21/11/2017 à 5:48 -
vinyloupMembre à l'essaiBonjour Buzut,
Tout d'abord merci pour cet article sur les conditions en BASH: pas toujours simple de s'y retrouver, c'est une bonne et bien pratique synthèse.
N'y aurait t'il pas un oubli sur l'exemple de la partie "I. Anatomie d'un if" . Le elif ne doit il pas être absolument suivi par un then ?
...
echo "le test est passé"
elif [ test2 ]
then
echo "le test2 est passé"
...le 31/10/2020 à 16:23 -
EscapetigerExpert éminent séniorDisons que c'est l'association string et ta mère qui m'a surpris (mais pas "choqué"
dans un premier temps.
Ensuite, je n'ai aucune légitimité "morale" sur ton travail, mais disons que par les temps qui courent il me semble plus judicieux d'utiliser un exemple "moins sexiste" et qui aura tendance à mal vieillir.
Je crois savoir que l'univers GNU / Linux est rempli de gens avec le sens de l'humour et qui aiment la nature, on y croise des gnous, des pingouins, des manchots, des renards, des pandas roux, des caméléons, etc.le 21/11/2017 à 14:53 -
BuzutMembre émériteBonjour,
Merci @N_BaH et @disedorgue pour vos retours éclairés.
Je vais faire une update rapidement en prenant en compte vos remarques !
Bonne journée.le 21/11/2017 à 13:37 -
EscapetigerExpert éminent séniorBonjour,
Bravo pour ce travail, juste une remarque de langage et sur l'exemple choisi :
Seul exemple en anglais parmi les autres termes français (on peut par exemple citer le terme courant anglais en introduction de paragraphe) :
II-A-2. Conditions sur les strings
et l'exemple choisi est "ta mère"le 21/11/2017 à 14:18 -
BuzutMembre émériteAh en effet, le "string" a du échapper aux correcteurs (je corrigerai ça aussi). C'est vrai que dans l'article original, je fais moins attention aux anglicismes.
Haha, bien vu pour "ta mère", je ne m'en souvenais même plusÇa fait une petite note d'humour.
Tu trouves cela déplacé sur Developpez ?
Merci de ta vigilancele 21/11/2017 à 14:23 -
BuzutMembre émériteBonjour,
@disedorgue, la syntaxe ternaire est "sympa" à connaître mais je ne sais pas si elle a un réel apport dans le cas d'une condition ? Aucun doute pour l'assignation mais pour le test, je n'ai pas de cas d'usage en tête.
Cordialement,le 29/11/2017 à 16:38 -
disedorgueExpert éminent séniorPeut-être bien que oui ou peut-être bien que non, par exemple ceci est permis (les couleurs pour montrer qui va avec qui) :
Code : if (( 1==1 ? 2==2 ? 3==3 ? 1 : 0 : 1 : 1 )) .....
le 29/11/2017 à 17:34