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.
Voici à quoi ressemble la première étape :
1 2 3 4 5 6 7 |
OPTS=$( getopt -o h -l home,nb_fichiers : – "$@" ) if [ $? != 0 ] then exit 1 fi eval set – "$OPTS" |
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 :
1 2 3 4 5 6 7 8 9 10 11 |
while true ; do case "$1" in -h) usage ; exit 0 ;; –home) showHome ; shift ;; –nb_fichiers) echo "Afficher le nombre de fichiers dans le répertoire $2"; shift 2 ;; –) shift ; break ;; esac done |
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 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#!/bin/bash function usage(){ printf "Utilisation du script :\n" printf "\t–home : affiche le chemin vers le home de l'utilisateur courant ;\n" printf "\t–nb_fichiers repertoire : affiche le nombre de fichiers contenus dans le répertoire ;\n" printf "\t‑h : affiche ce message.\n" } if [ $# -eq 0 ] then usage fi function showHome(){ echo "Home de l'utilisateur $USER"; echo $HOME ; } function nbFichiers(){ if [ -d $1 ] then nb=$( ls $1 | wc -l ) echo "$1 contient $nb fichiers et répertoires." else echo "Ce n'est pas un répertoire !" usage exit 0 fi } OPTS=$( getopt -o h -l home,nb_fichiers : – "$@" ) if [ $? != 0 ] then exit 1 fi eval set – "$OPTS" while true ; do case "$1" in -h) usage ; exit 0 ;; –home) showHome ; shift ;; –nb_fichiers) echo "Afficher le nombre de fichiers et répertoires dans le répertoire $2"; nbFichiers $2 ; shift 2 ;; –) shift ; break ;; esac done exit 0 |
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 !
Laisser un commentaire