IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Quelques bonnes pratiques dans l'écriture de scripts en Bash [Tutoriel]


Sujet :

Shell et commandes GNU

  1. #1
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut Quelques bonnes pratiques dans l'écriture de scripts en Bash
    Bonjour à tous.

    Je vous présente un nouveau cours faisant suite à celui-ci précédemment publié : Quelques bonnes pratiques dans l'écriture de scripts en Bash.

    Ce cours recense un ensemble de rappels et bonnes pratiques à privilégier dans l'écriture de scripts shell généralement implémentés en Bash. Il a été rédigé à partir d'erreurs couramment rencontrées au travail ou encore sur différents forums.

    Ce cours n'a pas pour vocation à reprendre les bases de la programmation de scripts shell et nécessite d'avoir quelques notions. Si ce n'est pas votre cas, nous vous recommandons fortement de lire ce cours au préalable.
    N'hésitez pas à laisser vos impressions ici.



    Idriss

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 376
    Points
    19 376
    Par défaut


    d'une manière générale, il manque des guillemets
    toutes les variables doivent être entre guillemets, sauf sis on sait pourquoi on ne le fait pas.
    les variables devraient être en minuscules; une variables tout en majuscules est une variable d'environnement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in "$dir/"*; do ... done
    tout ce qu'affiche echo doit être mis entre guillemets : le texte, les variables, les substitutions de commandes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "texte $variable $(subst)"
    II-B
    Une correction possible consiste à déléguer une partie du script au sous-shell :
    un sous-shell n'est pas obligatoire, une simple liste de commande suffit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls "$dir" | { while read; do nf="$REPLY"; done; echo "$nf";}
    III-B
    read peut lire plusieurs variables (cut ou awk sont inutiles)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while IFS=':' read nom reste; do echo "$nom"; done </etc/passwd
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Merci pour ces remarques pertinentes, je les intégrerais dans une prochaine version

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut

    Il aurait été interressant aussi de donner les cas d'utilisations des commandes tels que cat ou sort | uniq (d'ailleurs je pense que tu voulais dire sort fichier | uniq et non sort|uniq fichier, car là pour le coup...)
    Mais respect, Bon Boulot...
    Cordialement.

  5. #5
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Merci pour la coquille que je viens de corriger

  6. #6
    Membre actif
    Homme Profil pro
    Développeur
    Inscrit en
    Décembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 101
    Points : 256
    Points
    256
    Par défaut
    La ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [ "$var1" = "1" ] && echo "OK" || echo "KO"
    Ne fait probablement pas ce que tu veux qu'elle fasse.

    Dans le cas présent, ça fonctionne, mais c'est une mauvaise pratique.
    En effet la commande echo "KO" est exécutée si le test échoue ou si la commande echo "OK" échoue. Il faut l'imaginer comme une instruction C classique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (var=1 && cmd1() || cmd2()) {}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '{if($2 ~ /^[0-9]+$/){print $2}}' fichier # bonne façon de faire
    Contrairement à ce que dis le commentaire ce n'est pas la bonne façon de faire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '$2 ~ /^[0-9]+$/{print $2}' fichier # bonne façon de faire
    est bien mieux (bien plus dans l'esprit awk).

    Dans la partie « Éviter les processus inutiles », il faudrait à mon humble avis :
    • expliquer qu'utiliser les fonctionnalités avancées de bash cassent la compatibilité (des fois entre version de bash)
    • parler de ce mauvais cas d'usage qui est de remplacer dirname par ${var%/*} et basename par ${var##*/} (essayer avec var='/' et avec var='toto.h')


    De plus si pour les cas présents oui il faut éviter les processus inutiles, il y a des fois où il vaut mieux briser un traitement pour profiter de la puissance des pipes. Si un traitement prend un temps x, un passage par un pipe peut faire diviser ce temps par deux avec 2 processus bien séparés (il y a un overhead lié à l'utilisation du pipe à prendre en compte). Si le traitement d'une entrée prend alors un peu plus de temps (le temps initial plus l'overhead), le débit peut augmenter sensiblement.

  7. #7
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    En effet la commande echo "KO" est exécutée si le test échoue ou si la commande echo "OK" échoue. Il faut l'imaginer comme une instruction C classique
    Je suis au courant, mais pour autant je ne suis pas d'accord pour dire que c'est une mauvais pratique forcement (tout dépend de tes besoins)

    Bien souvent, même si le test renvoie vrai et que la commande en cas de succès échoue, il peut s'avérer utile d'exécuter le traitement en cas d’échec.

    En l'occurrence, je ne rentre pas dans ce détail, le but de cette partie étant d'expliquer qu'il faut protéger ses variables et utiliser les bons opérateurs (mission remplie à mon sens).

    Citation Envoyé par pour la partie awk
    Contrairement à ce que dis le commentaire ce n'est pas la bonne façon de faire.
    C'est une bonne façon de faire dans le sens ou l'on utilise pas plusieurs programmes pour effectuer un traitement. Sinon, je ne suis pas d'accord non plus : l'utilisation du if est une question de choix, il va falloir m'expliquer en quoi ta syntaxe (que je connais également mais j'ai estimé que pour les connaisseurs de bash non connaisseurs de awk, serait plus claire) est préférable...

    De plus, le but de cette partie était de montrer que bien souvent on pouvait limiter le nombre de processus utilisés dans un traitement et non débattre de la syntaxe awk.

    Cordialement,
    Idriss

  8. #8
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Bonjour,

    Citation Envoyé par barmic Voir le message
    La ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [ "$var1" = "1" ] && echo "OK" || echo "KO"
    Ne fait probablement pas ce que tu veux qu'elle fasse.

    Dans le cas présent, ça fonctionne, mais c'est une mauvaise pratique.
    En effet la commande echo "KO" est exécutée si le test échoue ou si la commande echo "OK" échoue.
    Ici, c'est tout de même très rare que le echo "..." echoue, mais bon pourquoi pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [ "$var1" = "1" ] && (echo "OK";true) || echo "KO"
    Comme true retourne toujours vrai...
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '{if($2 ~ /^[0-9]+$/){print $2}}' fichier # bonne façon de faire
    Contrairement à ce que dis le commentaire ce n'est pas la bonne façon de faire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '$2 ~ /^[0-9]+$/{print $2}' fichier # bonne façon de faire
    est bien mieux (bien plus dans l'esprit awk).
    ...
    Ici, cela ce discute, je ne suis pas expert sous awk, et donc ma question est de savoir comment on fait le else implicite dans la version du if implicite, c'est à dire, la correspondance de ce code par exemple ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '{if($2 ~ /^[0-9]+$/) {print $2} else {print $1}}'
    [hors sujet]A quand une discussion sur le choix selon les performances (temps, taille,...) attendues ?[/hors sujet]
    Cordialement.

  9. #9
    Membre actif
    Homme Profil pro
    Développeur
    Inscrit en
    Décembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 101
    Points : 256
    Points
    256
    Par défaut
    Citation Envoyé par ok.Idriss Voir le message
    Je suis au courant, mais pour autant je ne suis pas d'accord pour dire que c'est une mauvais pratique forcement (tout dépend de tes besoins)
    Bien pour ça que j'ai écris :
    Ne fait probablement pas ce que tu veux qu'elle fasse.
    Ici tu l'utilise comme un if-then-else ce qu'il n'est pas. Ça fonctionne uniquement parce que echo renvoie toujours 0 (c'est donc un cas particulier). Je pense que montrer des cas particulier à des débutants sans expliquer que c'est un cas particulier est une mauvaise pratique.

    Citation Envoyé par ok.Idriss Voir le message
    C'est une bonne façon de faire dans le sens ou l'on utilise pas plusieurs programmes pour effectuer un traitement. Sinon, je ne suis pas d'accord non plus : l'utilisation du if est une question de choix, il va falloir m'expliquer en quoi ta syntaxe (que je connais également mais j'ai estimé que pour les connaisseurs de bash non connaisseurs de awk, serait plus claire) est préférable...
    D'une part elle est plus courte. D'autre part sortir le test du bloc de traitement rend le code awk bien plus lisible. Tu vois tout de suite, la condition qui exécute ton programme ou pas.

    Citation Envoyé par ok.Idriss Voir le message
    De plus, le but de cette partie était de montrer que bien souvent on pouvait limiter le nombre de processus utilisés dans un traitement et non débattre de la syntaxe awk.
    Ça n'empêche pas de montrer des exemples le plus propre possible.

    Citation Envoyé par disedorgue Voir le message
    Ici, cela ce discute, je ne suis pas expert sous awk, et donc ma question est de savoir comment on fait le else implicite dans la version du if implicite, c'est à dire, la correspondance de ce code par exemple ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F " " '{if($2 ~ /^[0-9]+$/) {print $2} else {print $1}}'
    Dans ces cas là, soit en effet tu rentre la condition dans le bloc soit tu inverse la condition, soit tu positionne une variable dans ton premier bloc qui conditionne l'exécution du second. Énormément de codes awk sont simples et du genre condition → exécution. Si on entre les conditions dans les blocs, on arrive rapidement à des scripts du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #!/usr/bin/env awk
    {
    if ($1 == 'toto') {
       action1
    }
    else if ($1 == 'tata') {
       action2
    }
    }
    Alors qu'il est nettement plus lisible d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #!/usr/bin/env awk
    $1 == 'toto' {
       action1
    }
    $1 == 'tata' {
       action2
    }
    La règle AMHA devrait être : « si tu n'a pas une bonne raison de rentrer la condition dans le bloc, ne le fait pas ».

    [hors sujet]A quand une discussion sur le choix selon les performances (temps, taille,...) attendues ?[/hors sujet][/QUOTE]
    Je suis à peu près sûr que perl enfonce la plupart de ces outils (sauf sur la gestion du fs et des fichiers).
    Mais à mon humble avis il est compliqué de faire du benchmark dessus (mais ça m'intéresserait).

  10. #10
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Les 2 propositions de awk que tu donnes ne sont pas équivalentes ou soit il faut retirer le else soit avoir des tests en parfaite opposition.
    Cordialement.

  11. #11
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Re-bonjour.

    Citation Envoyé par barmic
    D'une part elle est plus courte. D'autre part sortir le test du bloc de traitement rend le code awk bien plus lisible. Tu vois tout de suite, la condition qui exécute ton programme ou pas.
    Elle un peu plus courte je veux bien (-4 caractères ). Plus lisible en revanche, c'est affaire de point de vue. Quand je fait des programmes awk complets (sur plusieurs lignes) je préfère avoir des blocs if-else bien définis.

    Ce que tu dit là c'est vraiment affaire de point de vue plus qu'autre chose, on ne peut pas prétendre quelle est la meilleure façon de faire.

    Citation Envoyé par barmic
    Alors qu'il est nettement plus lisible d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $1 == 'toto' {
       action1
    }
    $1 == 'tata' {
       action2
    }
    Sauf que tu ne fait pas la même chose, ton code revient à écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if($1 == 'toto') {
       action1
    }
    if ($1 == 'tata') {
       action2
    }
    Même si dans ton cas, $1 ne peut pas valoir 'toto' et 'tata' en même temps, dans d'autres cas ça n'aurait pas le comportement attendu

    Et encore une fois, ta vision de la lisibilité est TA vision. Dans la plupart des langages on écrit "if", "else" ... cela ne veut pas dire qu'il faille forcement bannir ta syntaxe mais elle n'est pas forcement meilleure que l'autre.

    Citation Envoyé par barmic
    Ici tu l'utilise comme un if-then-else ce qu'il n'est pas. Ça fonctionne uniquement parce que echo renvoie toujours 0 (c'est donc un cas particulier). Je pense que montrer des cas particulier à des débutants sans expliquer que c'est un cas particulier est une mauvaise pratique.
    D'une part, ce cours ne s'adresse pas aux débutants (le niveau "confirmé" est indiqué et il est écrit dans l'intro qu'il est préférable de lire ceci avant ou d'avoir acquis les bases ailleurs).

    D'autres part, relis ce que j'ai écris :

    Citation Envoyé par ok.Idriss
    Bien souvent, même si le test renvoie vrai et que la commande en cas de succès échoue, il peut s'avérer utile d'exécuter le traitement en cas d’échec.
    Ce n'est pas un cas particulier, pas plus que de choisir de faire un if...else. C'est une affaire de choix en fonction d'un besoin précis. N'ayant pas de besoin précis pour cette partie, j'ai fait ce choix là (que je pratique souvent dans les scripts).

    Citation Envoyé par barmic
    Je pense que montrer des cas particulier à des débutants sans expliquer que c'est un cas particulier est une mauvaise pratique.
    Je n'en ait jamais vu. Par définition une commande renvoie toujours un code de retour. Si tel n'est pas le cas, là effectivement on tombe dans un cas particulier (hors sujet avec le thème du chapitre).

    L'idée étant de montrer ce qui arrive quand on se trompe d'opérateur ou quand on ne protège pas ses variables => non pas de savoir si on a fait un if (condition) toto() else tata() ou if (condition && toto()) else tata(). L'explication par rapport au thème du chapitre sera exactement la même dans les deux cas.

    Citation Envoyé par barmic
    Ça n'empêche pas de montrer des exemples le plus propre possible.
    Affaire de point de vue, une fois de plus.

    Citation Envoyé par barmic
    Je suis à peu près sûr que perl enfonce la plupart de ces outils
    Ça troll là

    Cordialement,
    Idriss

  12. #12
    Membre actif
    Homme Profil pro
    Développeur
    Inscrit en
    Décembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 101
    Points : 256
    Points
    256
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Les 2 propositions de awk que tu donnes ne sont pas équivalentes ou soit il faut retirer le else soit avoir des tests en parfaite opposition.
    Dans le cas présent elles le sont. Comme j'ai dis :
    • soit tu inverse les conditions
    • soit tu utilise une variable d'état
    • soit en effet tu entre ta condition dans ton bloc

    Ici j'ai choisi la première solution.

    Citation Envoyé par ok.Idriss Voir le message
    Elle un peu plus courte je veux bien (-4 caractères ). Plus lisible en revanche, c'est affaire de point de vue. Quand je fait des programmes awk complets (sur plusieurs lignes) je préfère avoir des blocs if-else bien définis.
    Quand il y a un else c'est compréhensible mais sinon c'est se détourner de la syntaxe du langage.

    Citation Envoyé par ok.Idriss Voir le message
    Ce que tu dit là c'est vraiment affaire de point de vue plus qu'autre chose, on ne peut pas prétendre quelle est la meilleure façon de faire.
    Oui c'est une affaire de point de vu et à mon avis. Quand on utilise un langage on devrait réellement l'utiliser plutôt que de tenter de se contenter du plus petit dénominateur commun. Plus ton script est gros et plus tu va te retrouver soit à avoir un gros bloc qui fait tout soit à avoir un tas de condition, à mon humble avis utiliser correctement la syntaxe du langage ça consiste justement à placer la condition avant le bloc. Tu préfère systématiquement l'éviter ? Sinon tu l'utilise dans quel cas ? Si tu ne l'utilise pas c'est que tu utilise awk comme un C interprété avec un typage simplifié ce n'est pas fonctionnellement l'idée derrière awk. awk est fait pour traiter du texte ligne à ligne (en vrai bloc à bloc), avec une syntaxe la plus pratique possible pour faire ça.

    Citation Envoyé par ok.Idriss Voir le message
    Même si dans ton cas, $1 ne peut pas valoir 'toto' et 'tata' en même temps, dans d'autres cas ça n'aurait pas le comportement attendu
    Cf ma première remarque du présent commentaire.

    Citation Envoyé par ok.Idriss Voir le message
    Et encore une fois, ta vision de la lisibilité est TA vision. Dans la plupart des langages on écrit "if", "else" ... cela ne veut pas dire qu'il faille forcement bannir ta syntaxe mais elle n'est pas forcement meilleure que l'autre.
    Je pense que la lisibilité est intrinsèquement lié au langage que tu utilise. Si tu es un habitué des syntaxe C-like aucun programme lisp, haskel ou caml ne te paraîtra lisible. Privilégier ceux qui ne connaissent pas le langage aux bonnes pratiques du langage (c'est à dire utiliser les constructions de base du langage), c'est un choix qui me paraît mauvais. Il faut s'adapter au langage qu'on utilise.

    Citation Envoyé par ok.Idriss Voir le message
    D'une part, ce cours ne s'adresse pas aux débutants (c'est bien indiqué dans l'intro qu'il est préférable de lire ceci avant ou d'avoir acquis les bases ailleurs).
    Citation Envoyé par ok.Idriss Voir le message
    Ce n'est pas un cas particulier, pas plus que de choisir de faire un if...else. C'est une affaire de choix en fonction d'un besoin précis. N'ayant pas de besoin précis pour cette partie, j'ai fait ce choix là (que je pratique souvent dans les scripts).
    Tu montre l'utilisation de « [] && || » ce qu'il n'est pas. C'est différent si tu te sert de || pour gérer les cas d'erreur comme le classique « or die » de perl.
    Encore une fois ça ne fonctionne comme un if-then-else que dans des cas particulier. C'est comme ne pas protéger les variables avec "", ça ne fonctionne pas dans des cas particuliers.

    Citation Envoyé par ok.Idriss Voir le message
    Je n'en ait jamais vu. Par définition une commande renvoie toujours un code de retour. Si tel n'est pas le cas, là effectivement on tombe dans un cas particulier (hors sujet avec le thème du chapitre).
    Le problème n'est pas qu'elle ne renvoie pas de code, mais qu'elle renvoie un code différent de 0.

    Citation Envoyé par ok.Idriss Voir le message
    L'idée étant de montrer ce qui arrive quand on se trompe d'opérateur ou quand on ne protège pas ses variables => non pas de savoir si on a fait un if (condition) toto() else tata() ou if (condition && toto()) else tata(). L'explication par rapport au thème du chapitre sera exactement la même dans les deux cas.
    Oui mais vouloir expliquer de mauvaises habitudes en en présentant d'autres n'est pas une bonne idée (à moins que tu cherche à proposer un tome 2 bientôt )

    Citation Envoyé par ok.Idriss Voir le message
    Ça n'empêche pas de montrer des exemples le plus propre possible.
    Affaire de point de vue, une fois de plus.
    Je crois que ça clos le débat. C'est ton document tu en fait ce que tu veux. Mais si à chacun des arguments que je donne tu m'explique que c'est une histoire de point de vu, mais surtout que tu ne vois pas l'intérêt de montrer quelque chose de propre… C'est ton avis, il est subjectivement mauvais, mais c'est ton avis. Quand un professeur montre l'exemple, il est bon qu'il montre le meilleur possible et pas celui qu'il faudra désapprendre plus tard.


    Citation Envoyé par ok.Idriss Voir le message
    Je suis à peu près sûr que perl enfonce la plupart de ces outils
    Ça troll là
    C'est TON point de vu.

  13. #13
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Un petit (contre) exemple permit en awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo 24 2C | awk -F " " '$2 == "2C" {print "toto";$2="2B"};$2 == "2B" {print "titi"}'
    Ici, avec une version en if - else, ne me donnera pas le même résultat.
    Cordialement.

  14. #14
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut


    Je reste pas d'accord avec l'ensemble de tes arguments.

    Tout d'abord, je n'ai rien contre la syntaxe de tes tests en awk, il m'arrive également de l'utiliser (tu remarquera que contrairement à toi, j'ai en aucun cas affirmé que tes façons de faire étaient des mauvaises pratiques même si j'ai d'autres préférences). Pour autant, invoquer la lisibilité pour dire que telle pratique est mauvaise n'est pas un argument objectif (et donc recevable).

    Citation Envoyé par barmic
    Le problème n'est pas qu'elle ne renvoie pas de code, mais qu'elle renvoie un code différent de 0.
    Oui et bien, trouve moi une commande shell qui ne renvoi pas 0 en cas de succès. Si un programme ne respecte pas cette norme, il n'a rien à faire dans un test dans un script (oui je suis subjectif là).

    Si tu m'en trouve une, je veux bien tenter de reconsidérer cet argument (et encore).

    Citation Envoyé par barmic
    Oui mais vouloir expliquer de mauvaises habitudes en en présentant d'autres n'est pas une bonne idée
    Sauf que pour moi, ça n'est pas une mauvaise habitude, pas en considérant tes arguments. Le echo n'est pas un cas particulier : le fait que les commandes renvoient 0 en cas de succès est une norme. Ce sont pour les cas particuliers qu'il faudra adapter ce code...

    Citation Envoyé par barmic
    Je crois que ça clos le débat. C'est ton document tu en fait ce que tu veux. Mais si à chacun des arguments que je donne tu m'explique que c'est une histoire de point de vu, mais surtout que tu ne vois pas l'intérêt de montrer quelque chose de propre… C'est ton avis, il est subjectivement mauvais, mais c'est ton avis. Quand un professeur montre l'exemple, il est bon qu'il montre le meilleur possible et pas celui qu'il faudra désapprendre plus tard.
    J'y peut rien si ces arguments sont trop subjectifs (lisibilité par exemple) ou dépendent trop d'un contexte hors sujet (commande ne renvoyant pas 0 en cas de succès) pour que j'en tienne compte.

    Il y a eu pourtant dans cette discussions des mauvaises pratiques et des erreurs qui ont été signalées, certaines ont été corrigées, d'autres sont prévues pour une version prochaine (le fait qu'il soit pas utile d'ouvrir un sous-shell dans le cas d'un pipe par exemple).

    Citation Envoyé par barmic
    Citation Envoyé par ok.Idriss
    Citation Envoyé par barmic
    Je suis à peu près sûr que perl enfonce la plupart de ces outils
    Ça troll là
    C'est TON point de vu.
    Oui c'est sûr qu'amener Perl sur une discussion qui parle de bash et awk sur un forum Shell GNU, c'est pas un troll

    Je veux bien croire que Perl soit plus performant pour un certain nombre de choses, mais là n'est pas le sujet et c'est rentrer dans un débat trollesque (d'autant qu'il y a d'autres alternatives à Perl qui se défendent très bien).

    Bon, je crois également qu'il faut mettre fin à ce débat stérile.



    Idriss

  15. #15
    Membre habitué
    Homme Profil pro
    consultant ETL
    Inscrit en
    Septembre 2008
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : consultant ETL
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2008
    Messages : 97
    Points : 185
    Points
    185
    Par défaut variables
    en ce qui me concerne, je mets toujours les noms de variables entres accolades
    petit exemple pour illustré :
    DIR="/tmp"
    for file in ${DIR}/* ; do echo "le fichier ${file} a pour droits : $(stat -c '%A' ${file}) " ; done

  16. #16
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 376
    Points
    19 376
    Par défaut
    ce n'est utile que lorsqu'il y a un risque que ce qui suit immédiatement soit concaténé au nom de la variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ var=123
    $ echo "$varname"
     
    $ echo "${var}name"
    123name
    les méta-caractères, et autres signes ne pouvant entrer dans la composition d'un nom de variable, ne posent pas de problème.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Membre actif
    Homme Profil pro
    Développeur
    Inscrit en
    Décembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 101
    Points : 256
    Points
    256
    Par défaut
    Citation Envoyé par ok.Idriss Voir le message
    Tout d'abord, je n'ai rien contre la syntaxe de tes tests en awk, il m'arrive également de l'utiliser (tu remarquera que contrairement à toi, j'ai en aucun cas affirmé que tes façons de faire étaient des mauvaises pratiques même si j'ai d'autres préférences). Pour autant, invoquer la lisibilité pour dire que telle pratique est mauvaise n'est pas un argument objectif (et donc recevable).
    La pratique en awk c'est d'avoir une condition suivi d'un bloc. J'y peux rien c'est le man qui le dis. J'ai déjà expliqué plusieurs fois à mon avis quand utiliser les conditions à l'intérieur ou à l'exterieur. Si tu choisi d'ignorer mon propos.

    Citation Envoyé par ok.Idriss Voir le message
    Oui et bien, trouve moi une commande shell qui ne renvoi pas 0 en cas de succès. Si un programme ne respecte pas cette norme, il n'a rien à faire dans un test dans un script (oui je suis subjectif là).

    Si tu m'en trouve une, je veux bien tenter de reconsidérer cet argument (et encore).
    On s'en fout. D'une part un script shell ne se limite pas à lancer des builtins et des commandes issues de coreutils, mais surtout tu le montre comme un if-then-else et tu nous parle de l'utiliser comme un if-then-catch. La majorité du temps (toutes en faite dans les autres langages) tu ne veux pas que ton bloc else s'exécutent en cas d'erreur dans le bloc then. Ça peut être une bonne idée de présenter une syntaxe pour gérer les erreurs simple ainsi :
    mais ce n'est pas ce que tu montre dans ton exemple

    Un cas simple que j'ai vu la semaine dernière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [ cond ] && mount -o 'machin,truc' "${dir}" || mount -o 'machin2,truc2' "${dir}"
    Nous ne voulions pas que le second mount se fasse si le premier échouait (d'ailleurs ça nous a posé des problèmes du coup).

    Citation Envoyé par ok.Idriss Voir le message
    J'y peut rien si ces arguments sont trop subjectifs (lisibilité par exemple) ou dépendent trop d'un contexte hors sujet (commande ne renvoyant pas 0 en cas de succès) pour que j'en tienne compte.
    Et après on explique que les scripts shell ne sont pas fiable. Avoir un flot de contrôle qui marche que si toutes les programmes sont biens écris et qui sinon explose, ça ne me paraît être une bonne idée.

    Citation Envoyé par ok.Idriss Voir le message
    Il y a eu pourtant dans cette discussions des mauvaises pratiques et des erreurs qui ont été signalées, certaines ont été corrigées, d'autres sont prévues pour une version prochaine (le fait qu'il soit pas utile d'ouvrir un sous-shell dans le cas d'un pipe par exemple).
    Oui la différence c'est que les exemples que je met pour illustrer mon propos n'ont pas vocation à être considéré comme un cours. Sinon ils seraient expliquaient.

    Citation Envoyé par ok.Idriss Voir le message
    Oui c'est sûr qu'amener Perl sur une discussion qui parle de bash et awk sur un forum Shell GNU, c'est pas un troll
    Il manquait un smiley. La réponse était ironique parce que tu as passer ta journée à m'expliquer que tout était de mon point de vu. Néanmoins la différence entre perl, python et ruby. C'est que perl a était conçu dans l'optique de remplacer awk, grep et sed. Je n'étaillerais pas avec des exemples, j'ai l'impression que ça t'énerverait.

    Citation Envoyé par ok.Idriss Voir le message
    Bon, je crois également qu'il faut mettre fin à ce débat stérile.
    Ne t'inquiète pas. À moins que tu sorte de l'argumentaire simpliste, je ne répondrais plus non plus.

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Mon petit grain de sel sur la syntaxe awk dont je suis un utilisateur régulier.

    la forme condition {action} est plus "awky" que celle {if(condition){action}}. Les deux sont syntaxiquement correctes et sont tout aussi performantes l'une que l'autre mais la deuxième pique effectivement aux yeux des habitués de awk. Avec un snippet utilisant la deuxième, on se fait vite remonter les bretelles sur unix.com. Pas pour une raison d'efficacité mais plutôt par convention de codage. Awk est construit sur le modèle condition{action}. C'est une de ses particularités.

    Mais, chacun fait son code comme il l'entend.

    Bon, maintenant j'allume un contre feu (no troll intended!)

    Les conseils du cours sont bons et mettent en évidence les erreurs les plus courantes. Je regrette simplement - et c'est une remarque générale sur ce forum "Shell et commandes Linux" - que les solutions proposées soient souvent non portables (non POSIX) car utilisent de nombreux bashismes.

    Debian et sa famille utilisent par défaut le shell dash beaucoup plus rapide et léger et la plupart des solutions que je lis ici ne fonctionneront pas sur un shell POSIX.

    Un bon article sur les raisons d'avoir choisi un shell POSIX:
    https://wiki.ubuntu.com/DashAsBinSh

    Bien sûr, il s'agit d'un cours sur bash. Et la syntaxe qui y est recommandée est conforme au bash. Mais ne pourrait-on pas encourager les lecteurs et rédacteurs de ce forum à purger les scripts des bashismes et les rendre ainsi plus portables?

    Et si on a besoin de plus de fonctionnalités il y a toujours awk, perl ou python pour écrire des scripts plus évolués.

    Mais peut-être est-ce là un autre débat...
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  19. #19
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 376
    Points
    19 376
    Par défaut
    Citation Envoyé par ripat
    il s'agit d'un cours sur bash
    voilà, tout est dit.

    et pourquoi ne pas limiter l'emploi de ksh aux seules syntaxes POSIX ?
    plusieurs shells, plusieurs syntaxes, plus de richesse !
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  20. #20
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 273
    Points : 12 708
    Points
    12 708
    Par défaut
    Même si j'ai pas mal insisté sur la syntaxe du awk, j'utilise moi même plus souvent la syntaxe condition {action}.

    Concernant les commandes en mode posix, on y prête beaucoup plus attention sur le forum qui lui est dédier: http://www.developpez.net/forums/f17...mmandes-posix/
    Cordialement.

Discussions similaires

  1. Quelques bonnes pratiques dans l'écriture de scripts en Bash
    Par ok.Idriss dans le forum Shell et commandes POSIX
    Réponses: 0
    Dernier message: 28/08/2013, 21h09
  2. Quelques bonnes pratiques dans l'écriture de scripts en Bash
    Par ok.Idriss dans le forum Contribuez
    Réponses: 0
    Dernier message: 28/08/2013, 21h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo