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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 : 34
    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
    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 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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 : 34
    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
    Par défaut
    Merci pour ces remarques pertinentes, je les intégrerais dans une prochaine version

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 361
    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 361
    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...

  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 : 34
    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
    Par défaut
    Merci pour la coquille que je viens de corriger

  6. #6
    Membre confirmé
    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
    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
    Membre éprouvé
    Homme Profil pro
    consultant ETL
    Inscrit en
    Septembre 2008
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : consultant ETL
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2008
    Messages : 97
    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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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.

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    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...

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    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.

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 361
    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 361
    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/

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