Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Apprendre à maîtriser les conditions en bash


Sujet :

Shell et commandes GNU

  1. #1
    Membre émérite
    Apprendre à maîtriser les conditions en bash
    Chers membres du club,

    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.
    Bonne lecture

    Retrouvez les meilleurs cours et tutoriels pour apprendre le système Linux.

  2. #2
    Modérateur

    Bonjour,


    Par ailleurs, on trouvera des crochets en lieu et place des habituelles parenthèses.
    non.
    d'ailleurs "habituelles" par rapport à quoi ?
    la syntaxe de if est
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
     if COMMANDES; then COMMANDES; [ elif COMMANDES; then COMMANDES; ]... [ else COMMANDES; ] fi

    c'est-à-dire que les crochets, en fait, sont une commande, et plus exactement un synonyme de la commande test.
    donc, il est possible d'écrire
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    if grep -q ":${USER}:" /etc/passwd; then echo "$USER est un utilisateur"; else echo "$USER n'est pas un utilisateur"; fi


    c'est pourquoi on est quelques uns à préconiser l'emploi de test, plutôt que les crochets, pour éviter ce contresens. à un caractère près , c'est égal, et plus éloquent.


    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
    pourquoi "simili" ?


    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.
    bof.


    les conditions simples ne requièrent pas if.
    pour reprendre mon exemple précédent :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    grep -q ":${USER}:" /etc/passwd && echo "$USER existe" || echo "$USER n'existe pas"
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  3. #3
    Expert éminent sénior
    Pour ma part, il y a des lacunes dans les explications, exemple:
    Syntaxe invalide mais pas d'erreur:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    $ [ 1=1 ] && echo ok
    ok

    La même mais cette fois la syntaxe est valide:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    $ [ 1 = 1 ] && echo ok
    ok

    Les espaces ne sont pas uniquement entre les crochets ouvrant et fermant.

    Il manque aussi les expressions du type:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ [ 1 = 1 -o 2 = 1 ] && echo ok
    ok
    $ [ 1 = 1 -a 2 = 2 ] && echo ok
    ok

    Et un autre sympathique:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    $ if (( 1==1 ? 0 : 1 )) ; then echo ok ; else echo ko ; fi
    ko

    que l'on peut aussi exploiter comme ceci:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo $(( 1==1 ? 5 : 6 ))
    5
    $ echo $(( 1==0 ? 5 : 6 ))
    6

    @N_BaH: même si tu précise dans les cas simple, soyons plus précis pour:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    grep -q ":${USER}:" /etc/passwd && echo "$USER existe" || echo "$USER n'existe pas"

    Le but ici, c'est que la partie à droite du '&&' doit toujours être vrai sinon la partie ou (à droite du '||' ) s’exécutera aussi.
    Donc la syntaxe simplifier doit sous entendre la syntaxe complète suivante:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    grep -q ":${USER}:" /etc/passwd && { echo "$USER existe" ; true ; } || echo "$USER n'existe pas"
    Cordialement.

  4. #4
    Membre émérite
    Bonjour,

    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.

  5. #5
    Expert éminent
    Bonjour,
    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"
    On parle bien de chaîne de caractères...
    https://documentcyborg.com
    Transform any web page into a document
    Copy and paste the following URL to try it : https://documentcyborg.com/faq

    Liste des balises BB - Forum du club des développeurs et IT Pro
    Jeu de balises basé sur le langage HTML - Permettent d'ajouter, de formater vos messages avec une syntaxe plus simple et ne déformera pas l'affichage des pages...

    Les meilleurs cours et tutoriels sur la programmation et l'informatique professionnelle - developpez.com

  6. #6
    Membre émérite
    Ah 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 vigilance

  7. #7
    Expert éminent
    Disons 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.
    https://documentcyborg.com
    Transform any web page into a document
    Copy and paste the following URL to try it : https://documentcyborg.com/faq

    Liste des balises BB - Forum du club des développeurs et IT Pro
    Jeu de balises basé sur le langage HTML - Permettent d'ajouter, de formater vos messages avec une syntaxe plus simple et ne déformera pas l'affichage des pages...

    Les meilleurs cours et tutoriels sur la programmation et l'informatique professionnelle - developpez.com

  8. #8
    Rédacteur

    Bonjour.

    Je plussoie pour l'imprécision de la phrase "Par ailleurs, on trouvera des crochets en lieu et place des habituelles parenthèses."

    Originellement [CODEINLINE][[/CODEINLINE] 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 :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ineumann ~ $ [ "u" = "v" ]
    ineumann ~ $ echo $?
    1
    ineumann ~ $ [ "u" = "u" ]
    ineumann ~ $ echo $?
    0


    On la retrouve d'ailleurs dans /bin sur certains OS :
    [CODE]ineumann ~ $ ls -l /bin/[ -rwxr-xr-x. 1 root root 53264 Oct 31 2016 '/bin/['[/CODE]

    Dans les versions modernes de bash c'est un builtin au même titre que [CODEINLINE][[[/CODEINLINE] qui est bien souvent préférable, voir ceci : Protéger ses opérandes

    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 [CODEINLINE][[/CODEINLINE] : 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,
    Idriss

  9. #9
    Membre émérite
    Bonjour,

    @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,

  10. #10
    Expert éminent sénior
    Peut-être bien que oui ou peut-être bien que non, par exemple ceci est permis (les couleurs pour montrer qui va avec qui) :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    if (( 1==1 ? 2==2 ? 3==3 ? 1 : 0 : 1 : 1 )) .....
    Cordialement.

###raw>template_hook.ano_emploi###