Astuce :
Astuce : ajouter des options dans un script Bash avec getopt

But : comprendre le fonctionnement de getopt en Bash pour éviter la multiplications de script là où un seul générique pourrait suffire.

Prérequis : savoir faire des scripts Bash, connaître la substitution de commande et savoir manipuler les arguments.

Difficulté : 2 (moyen)

Pour ceux qui codent en Perl, vous connaissez déjà sûrement le module GetOpt et plus particulièrement son extension GetOpt::Long (ou encore le module getopt du langage Python). Mais pour ceux qui souhaitent juste faire un script qui enchaine les grep et les cut pour pouvoir compter le nombre d'occurence d'une clé en fonction de certains critères, il peut être utile de pouvoir le faire uniquement en Bash plutôt que de se lancer dans un script Perl de plus. Dans cet article, je me propose donc de vous présenter la commande getopt illustrée d'un exemple simple.

Script bash en cours d'édition sous VIM

Script bash en cours d'édition sous VIM (auteur : Nolwenn) | Licence Art Libre

Voici à quoi ressemble la première étape :

Ligne 1 :

  • getopt est le nom de la commande
  • -o pour les options courtes, c'est à dire une lettre par option
    • h sera une option courte, pour afficher l'aide par exemple
  • -l pour les options longues, c'est à dire un ensemble de lettres, comme un mot
    • home sera une option longue simple
    • nb_fichiers: sera une option longue attendant un argument en paramètre
  • - - pour le comportement par défaut

Pour analyser les options, on utilise une boucle :

Analysons cette portion de code :

  • while true; do [..] done : une simple boucle while qui sera exécutée jusqu'à ce que le script soit terminé ;
  • case $1 in [..] esac : on regarde le premier argument et on compare son résultat à l'un des cas attendus par le script ;
  • -h : si $1 vaut -h, alors on exécute la fonction usage() et on termine le script ;
  • - -home : si $1 vaut - -home, alors on exécute la fonction showHome() et on supprime l'argument $1 ;
  • - -nb_fichiers : si $1 vaut - -nb_fichiers, alors on affiche la ligne avec le nom du répertoire donné dans $2 et on supprime les arguments $1 et $2 ;
  • - - : si $1 vaut - - on supprime l'argument $1 et on effectue un break (comportement de fin attendu par case [..] esac)

Le script final, de mon cru et sous licence GPL ;), pourra ainsi ressembler à ceci :

Vous voilà parés pour faire de jolis scripts Shell/Bash complexes avec des arguments et des options dans tous les sens 😉 !


Un grand merci à Hautbit et Yoann M. pour leur relecture et nos discussions.
Un remerciement tout particulier à Sylvain P. pour m'avoir fait découvrir cette merveilleuse commande Bash !

  • À propos de
  • Issue d'une licence de biologie cellulaire et physiopathologie et d'un master de bioinformatique, je m'intéresse tout particulièrement au monde de la recherche et au domaine de la santé. J'ai travaillé dans l'unité 946 de l'INSERM, dirigée par Florence Demenais, où mon travail principal a été l'étude et la recherche de bases de données et d'outils d'intérêt majeur pour l'axe de recherche dans lequel j'étais impliquée. J'ai aussi travaillé à l'Institut Pasteur où j'ai été recrutée en tant qu'ingénieure bioinformaticienne dans le cadre du LabEx Milieu Intérieur et où ma mission principale a été de mettre en place une base de données pour la gestion de nos échantillons biologiques. Mes centres d'intérêt en bioinformatique sont : la mise en application de méthodes dans les domaines de la génomique, de la protéomique et les interactions gène-gène protéine-protéine pouvant nous apporter des informations sur leurs influences dans les maladies. Je travaille actuellement au service informatique de l'IBENS où j'ai été recrutée en qualité de développeuse d'applications !

Catégorie: Astuce | Tags: , , , ,

8 commentaires sur “Astuce : ajouter des options dans un script Bash avec getopt

  1. Salut,

    Une remarque sur le code bash, pas sur getopt qui est bien présenté (même si par nature, ça fait très formule magique comme fonction).

    $ mkdir "repertoire avec espaces"
    $ bash ./test_getopts.sh --nb repertoire\ avec\ espaces/
    Ce n'est pas un répertoire !
    ...

    Quand on n'a pas la maîtrise de ce qui entre comme dans le cas d'une action d'un utilisateur (!), il faut être très prudent et blinder le code.

    Les variables sont à protéger avec "$1" ou même "${1}".

    Bonne continuation.
    KooK

    • Merci pour l'astuce, il est vrai que je n'y ai pas pensé du tout, étant donné que j'ai pris l'habitude de ne jamais mettre d'espace dans un nom de répertoire/fichier. Ce qui n'est malheureusement pas toujours le cas de tout le monde, nous avons chacun nos petite manies. En plus, j'ai appris une nouvelle astuce de programmation 😉 !

  2. bonjour,

    j'aimerai savoir comment faire si je veux à la fois rentrer 3 options. par exemple pour une connexion à un switch j'ai besoin de 3 options longues.

    merci pour toute aide.
    phi.

    • Bonjour,

      il vous suffit de saisir dans le switch autant d'options que nécessaires puis de gérer le traitement des options renseignées.
      Vous n'aurez alors qu'à saisir vos trois options longues les unes à la suite des autres comme dans n'importe quel programme. getopt est vraiment simple à utiliser une fois que l'on a compris le fonctionnement de base 🙂 !

      Cordialement,
      Nolwenn

  3. En essayant d'intégrer des options proprement dans un script, j'ai lu que finalement getopt n'est pas forcément une bonne recommandation parce que non standard et implémenté de façons différentes.

    Ici : http://mywiki.wooledge.org/BashFAQ/035
    on trouve différentes propositions pour analyser les options.

    Il me semble que du coup le code de cet article fonctionnerait tout aussi bien sans getopt, avec juste la boucle.

    • Bonjour KooK,

      merci beaucoup pour cette remontée d'informations. Je vous avoue que je suis surprise étant donné que j'avais lu l'inverse l'année dernière, quelques semaines avant de rédiger cet article. Les normes auraient-elles changé aussi vite ?
      Si vous avez l'occasion de tester la boucle sans getopt(s), je serais ravie d'en connaître le verdict 🙂 !

      Cordialement, Nolwenn

  4. Si mes souvenirs sont bons, j'avais géré mes arguments dans un script Bash avec une boucle identique, mais sans getop.
    Donc je pense que ça marche.

  5. Merci pour ce tuto :). C'est exactement ce dont j'avais besoin: un tuto avec un exemple simple pour comprendre rapidement comment faire un script bash avec des options. C'est quand même plus agréable que de se perdre dans les limbes d'internet sur des modes d'emploi abscons de 42 pages…
    En revanche, pour que ce script fonctionne chez moi (Mac OSX 10.6.8), j'ai dû:
    — commenter «eval set -- "$OPTS"»
    — remplacer le «true» de la boucle «while» par un booléen valant «true» si «$# != 0» et «false» si aucun argument «$# == 0», car sinon, après l'appel de «usage», l'exécution rentrait dans la boucle «while» qui itérait à l'infini (et c'est long l'infini, surtout vers la fin!)

Laisser un commentaire