Comment utiliser les tests conditionnels à double crochet sous Linux
Agence web » Actualités du digital » Comment utiliser getops pour analyser les options de script du shell Linux

Comment utiliser getops pour analyser les options de script du shell Linux

Souhaitez-vous que vos scripts shell Linux gèrent plus gracieusement les options et les arguments de la ligne de commande ? La fête getopts builtin vous permet d’analyser les options de ligne de commande avec finesse – et c’est aussi facile. Nous vous montrons comment.

Présentation de la fonction intégrée getopts

Qui passe valeurs dans un script Bash est assez simple. Vous appelez votre script à partir de la ligne de commande ou d’un autre script et fournissez votre liste de valeurs derrière le nom du script. Ces valeurs sont accessibles dans votre script en tant que variables, en commençant par $1 pour la première variable, $2 pour le second et ainsi de suite.

Mais si tu veux passer choix à un scénario, la situation devient rapidement plus complexe. Lorsque nous parlons d’options, nous entendons les options, les drapeaux ou les commutateurs que les programmes aiment ls peut gérer. Ils sont précédés d’un tiret « -” et servent généralement d’indicateur au programme pour activer ou désactiver certains aspects de ses fonctionnalités.

le ls La commande a plus de 50 options, principalement liées au formatage de sa sortie. le -X (trier par extension) trie la sortie alphabétiquement par extension de fichier. le -U (non triées) listes d’options par ordre de répertoire.

Les options ne sont que cela : elles sont facultatives. Vous ne savez pas quelles options, le cas échéant, l’utilisateur va choisir d’utiliser, et vous ne savez pas non plus dans quel ordre il peut les lister sur la ligne de commande. Cela augmente la complexité du code requis pour analyser les options.

Les choses se compliquent encore si certaines de vos options prennent un argument, connu sous le nom de argument d’optionPar exemple, le ls -w (width) s’attend à être suivie d’un nombre, représentant la largeur d’affichage maximale de la sortie. Et bien sûr, vous pourriez passer d’autres paramètres dans votre script qui sont simplement des valeurs de données, qui ne sont pas du tout des options.

Heureusement getopts gère cette complexité pour vous. Et parce que c’est un intégré, il est disponible sur tous les systèmes qui ont le shell Bash, donc il n’y a rien à installer.

Remarque : getops Pas getopt

Il existe un ancien utilitaire appelé getopt . C’est un petit utilitaire programme, pas une fonction intégrée. Il existe de nombreuses versions différentes de getopt avec des comportements différents, alors que les getops builtin suit les directives POSIX.

type getopts
type getopt

en utilisant la commande type pour voir la différence entre getop et getops

Parce que getopt n’est pas intégré, il ne partage pas certains des avantages automatiques que getopts fait, comme la gestion raisonnable des espaces blancs. Avec getopts, le shell Bash exécute votre script et le shell Bash effectue l’analyse des options. Vous n’avez pas besoin d’invoquer un programme externe pour gérer l’analyse.

Le compromis est getopts ne gère pas les noms d’options au format long en double tiret. Vous pouvez donc utiliser des options formatées comme -w mais non  » ---wide-format.” Par contre, si vous avez un script qui accepte les options -a , -b et -c , getopts vous permet de les combiner comme -abc, -bcaou -bac etc.

Nous discutons et démontrons getopts dans cet article, assurez-vous donc d’ajouter le « s » final au nom de la commande.

EN RELATION: Comment échapper aux espaces dans les chemins de fichiers sur la ligne de commande Windows

Un récapitulatif rapide : gestion des valeurs de paramètre

Ce script n’utilise pas d’options en pointillés comme -a ou -b . Il accepte les paramètres « normaux » sur la ligne de commande et ceux-ci sont accessibles à l’intérieur du script en tant que valeurs.

#!/bin/bash

# get the variables one by one
echo "Variable One: $1" 
echo "Variable Two: $2" 
echo "Variable Three: $3"

# loop through the variables
for var in "$@" do 
  echo "$var" 
done

Les paramètres sont accessibles à l’intérieur du script en tant que variables $1, $2ou $3 .

Copiez ce texte dans un éditeur et enregistrez-le dans un fichier appelé « variables.sh ». Nous devrons le rendre exécutable avec le chmod commander. Vous devrez effectuer cette étape pour tous les scripts dont nous discutons. Remplacez simplement le nom du fichier de script approprié à chaque fois.

chmod +x variables.sh

utiliser la commande chmod pour rendre un script exécutable

Si nous exécutons notre script sans paramètres, nous obtenons cette sortie.

./variables.sh

exécuter un script sans paramètres

Nous n’avons passé aucun paramètre, le script n’a donc aucune valeur à signaler. Donnons quelques paramètres cette fois.

./variables.sh how to geek

exécuter un script avec trois mots comme paramètres

Comme prévu, les variables $1, $2 et $3 ont été définis sur les valeurs des paramètres et nous les voyons imprimés.

Ce type de gestion des paramètres un pour un signifie que nous devons savoir à l’avance combien de paramètres il y aura. La boucle au bas du script ne se soucie pas du nombre de paramètres, elle les parcourt toujours tous.

Si nous fournissons un quatrième paramètre, il n’est pas affecté à une variable, mais la boucle le gère toujours.

./variables.sh how to geek website

passer quatre paramètres à un script qui ne peut en gérer que trois

Si nous mettons des guillemets autour de deux des mots, ils sont traités comme un seul paramètre.

./variables.sh how "to geek"

citer deux paramètres de ligne de commande pour les traiter comme un seul paramètre

Si nous voulons que notre script gère toutes les combinaisons d’options, d’options avec arguments et de paramètres de type de données « normaux », nous devrons séparer les options des paramètres normaux. Nous pouvons y parvenir en plaçant toutes les options, avec ou sans arguments,avant de les paramètres réguliers.

Mais ne courons pas avant de pouvoir marcher. Examinons le cas le plus simple pour gérer les options de ligne de commande.

Options de manipulation

Nous utilisons getopts dans un while boucle. Chaque itération de la boucle fonctionne sur une option qui a été transmise au script. Dans chaque cas, la variable OPTION est défini sur l’option identifiée par getopts.

A chaque itération de la boucle, getopts passe à l’option suivante. Lorsqu’il n’y a plus d’options, getopts Retour false et le while sorties de boucle.

le OPTION La variable est mise en correspondance avec les modèles de chacune des clauses de l’instruction case. Comme nous utilisons une instruction case, peu importe l’ordre dans lequel les options sont fournies sur la ligne de commande. Chaque option est déposée dans l’instruction case et la clause appropriée est déclenchée.

Les clauses individuelles de l’instruction case facilitent l’exécution d’actions spécifiques à une option dans le script. En règle générale, dans un script réel, vous définiriez une variable dans chaque clause, et celles-ci agiraient comme des drapeaux plus loin dans le script, autorisant ou refusant certaines fonctionnalités.

Copiez ce texte dans un éditeur et enregistrez-le en tant que script appelé « options.sh », et rendez-le exécutable.

#!/bin/bash

while getopts 'abc' OPTION; do
  case "$OPTION" in 
    a) 
      echo "Option a used" ;;

    b)
      echo "Option b used"
      ;;

    c)
      echo "Option c used"
      ;;

    ?) 
      echo "Usage: $(basename $0) [-a] [-b] [-c]"
      exit 1
      ;;
  esac
done

C’est la ligne qui définit la boucle while.

while getopts 'abc' OPTION; do

le getopts la commande est suivie de la chaîne d’options. Ceci répertorie les lettres que nous allons utiliser comme options. Seules les lettres de cette liste peuvent être utilisées comme options. Donc dans ce cas, -d serait invalide. Celui-ci serait piégé par le ?) clause parce que getopts renvoie un point d’interrogation « ?” pour une option non identifiée. Si cela se produit, l’utilisation correcte est imprimée dans la fenêtre du terminal :

echo "Usage: $(basename $0) [-a] [-b] [-c]"

Par convention, mettre une option entre parenthèses « []” dans ce type de message d’utilisation correcte signifie que l’option est facultative. La commande basename supprime tous les chemins de répertoire du nom de fichier. Le nom du fichier de script est contenu dans $0 dans les scripts Bash.

Utilisons ce script avec différentes combinaisons de ligne de commande.

./options.sh -a
./options.sh -a -b -c
./options.sh -ab -c
./options.sh -cab

tester un script qui peut accepter les options de ligne de commande de type commutateur

Comme nous pouvons le voir, toutes nos combinaisons d’options de test sont analysées et gérées correctement. Et si on essayait une option qui n’existe pas ?

./options.sh -d

Une option non reconnue signalée par le shell et le script

La clause d’utilisation est déclenchée, ce qui est bien, mais nous recevons également un message d’erreur du shell. Cela peut ou non avoir de l’importance pour votre cas d’utilisation. Si vous appelez le script à partir d’un autre script qui doit analyser les messages d’erreur, cela compliquera la tâche si le shell génère également des messages d’erreur.

Désactiver les messages d’erreur du shell est très simple. Tout ce que nous avons à faire est de mettre deux-points ” : ” comme premier caractère de la chaîne d’options.

Modifiez votre fichier « options.sh » et ajoutez deux points comme premier caractère de la chaîne d’options, ou enregistrez ce script sous « options2.sh » et rendez-le exécutable.

#!/bin/bash

while getopts ':abc' OPTION; do
  case "$OPTION" in 
    a) 
      echo "Option a used" 
      ;;

    b)
      echo "Option b used"
      ;;

    c)
      echo "Option c used"
      ;;

    ?) 
      echo "Usage: $(basename $0) [-a] [-b] [-c]"
      exit 1
      ;;
  esac
done

Lorsque nous exécutons ceci et générons une erreur, nous recevons nos propres messages d’erreur sans aucun message shell.

./options2.sh.sh -d

Une option non reconnue signalée par le script seul

Utilisation de getops avec des arguments d’option

Dire getopts qu’une option sera suivie d’un argument, mettez deux-points ” : ” immédiatement après la lettre d’option dans la chaîne d’options.

Si nous suivons les « b » et « c » dans notre chaîne d’options avec deux-points, getopt attendra des arguments pour ces options. Copiez ce script dans votre éditeur et enregistrez-le sous « arguments.sh », et rendez-le exécutable.

Se souvenir du première deux-points dans la chaîne d’options est utilisé pour supprimer les messages d’erreur du shell – cela n’a rien à voir avec le traitement des arguments.

Lorsque getopt traite une option avec un argument, l’argument est placé dans le OPTARG variable. Si vous souhaitez utiliser cette valeur ailleurs dans votre script, vous devrez la copier dans une autre variable.

#!/bin/bash

while getopts ':ab:c:' OPTION; do

  case "$OPTION" in
    a)
      echo "Option a used"
      ;;

    b)
      argB="$OPTARG"
      echo "Option b used with: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Option c used with: $argC"
      ;;

    ?)
      echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]"
      exit 1
      ;;
  esac

done

Exécutons cela et voyons comment cela fonctionne.

./arguments.sh -a -b "how to geek" -c reviewgeek
./arguments.sh -c reviewgeek -a

tester un script capable de gérer les arguments d'option

Nous pouvons donc maintenant gérer les options avec ou sans arguments, quel que soit l’ordre dans lequel elles sont données sur la ligne de commande.

Mais qu’en est-il des paramètres réguliers ? Nous avons dit plus tôt que nous savions que nous devions les mettre sur la ligne de commande après toutes les options. Voyons ce qui se passe si nous le faisons.

Options et paramètres de mélange

Nous allons modifier notre script précédent pour inclure une ligne supplémentaire. Quand le while boucle est terminée et que toutes les options ont été gérées, nous allons essayer d’accéder aux paramètres normaux. Nous imprimerons la valeur dans $1 .

Enregistrez ce script sous « arguments2.sh » et rendez-le exécutable.

#!/bin/bash

while getopts ':ab:c:' OPTION; do

  case "$OPTION" in
    a)
      echo "Option a used"
      ;;

    b)
      argB="$OPTARG"
      echo "Option b used with: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Option c used with: $argC"
      ;;

    ?)
      echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]"
      exit 1
      ;;
  esac

done

echo "Variable one is: $1"

Nous allons maintenant essayer quelques combinaisons d’options et de paramètres.

./arguments2.sh dave
./arguments2.sh -a dave
./arguments2.sh -a -c how-to-geek dave

Impossible d'accéder aux paramètres standard dans un script qui accepte les arguments d'option

Alors maintenant, nous pouvons voir le problème. Dès que des options sont utilisées, les variables $1 sont remplis avec les drapeaux d’option et leurs arguments. Dans le dernier exemple, $4 contiendrait la valeur de paramètre « dave », mais comment y accéder dans votre script si vous ne savez pas combien d’options et d’arguments vont être utilisés ?

La réponse est d’utiliser OPTIND et le shift commander.

le shift La commande supprime le premier paramètre, quel que soit son type, de la liste des paramètres. Les autres paramètres sont « décroissants », donc le paramètre 2 devient le paramètre 1, le paramètre 3 devient le paramètre 2, et ainsi de suite. Et donc $2 devient $1 , $3 devient $2 etc.

Si vous fournissez shift avec un nombre, cela supprimera autant de paramètres de la liste.

OPTIND compte les options et les arguments au fur et à mesure qu’ils sont trouvés et traités. Une fois que toutes les options et tous les arguments ont été traités OPTIND sera supérieur d’un au nombre d’options. Donc, si nous utilisons shift pour couper (OPTIND-1) paramètres hors de la liste des paramètres, il nous restera les paramètres réguliers dans $1 À partir de.

C’est exactement ce que fait ce script. Enregistrez ce script sous « arguments3.sh » et rendez-le exécutable.

#!/bin/bash

while getopts ':ab:c:' OPTION; do
  case "$OPTION" in
    a)
      echo "Option a used"
      ;;

    b)
      argB="$OPTARG"
      echo "Option b used with: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Option c used with: $argC"
      ;;

    ?)
      echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]"
      exit 1
      ;;
  esac
done

echo "Before - variable one is: $1"
shift "$(($OPTIND -1))"
echo "After - variable one is: $1"
echo "The rest of the arguments (operands)"

for x in "$@"
do
  echo $x
done

Nous allons l’exécuter avec un mélange d’options, d’arguments et de paramètres.

./arguments3.sh -a -c how-to-geek "dave dee" dozy beaky mick tich

Accéder correctement aux paramètres standard dans un script qui accepte les arguments d'option

Nous pouvons le voir avant d’appeler shift , $1 maintenu « -a », mais après la commande shift $1 contient notre premier paramètre sans option ni argument. Nous pouvons parcourir tous les paramètres aussi facilement que dans un script sans analyse d’option.

C’est toujours bien d’avoir des options

La gestion des options et de leurs arguments dans les scripts n’a pas besoin d’être compliquée. Avec getopts vous pouvez créer des scripts qui gèrent les options de ligne de commande, les arguments et les paramètres exactement comme le devraient les scripts natifs compatibles POSIX.

★★★★★