GNU/Linux >> Tutoriels Linux >  >> Linux

Ajouter des arguments et des options à vos scripts Bash

L'automatisation est l'un des outils les plus importants pour la plupart des administrateurs système. Nous écrivons et maintenons des scripts pour automatiser les tâches courantes et fréquentes que nous devons effectuer.

J'ai des dizaines de scripts - courts et longs - que j'ai écrits et modifiés au fil des ans. Certains de mes scripts les plus utiles ont été d'effectuer des sauvegardes régulières tôt chaque matin, d'installer des packages logiciels mis à jour avec des correctifs et des améliorations, et de passer d'une version de Fedora à la suivante. Je viens de mettre à niveau tous mes hôtes et serveurs personnels vers Fedora 34 il y a quelques jours en utilisant un script assez simple.

[ Vous pourriez également aimer : Plus d'astuces Bash stupides :variables, recherche, descripteurs de fichiers et opérations à distance ]

Deux des choses les plus courantes que je fais pour tous mes scripts sont la création d'une fonction d'aide et d'une fonction qui affiche la déclaration de licence GPL3. J'aime inclure des modes verbeux ou de test pour aider à la détermination des problèmes dans mes scripts. Dans certains scripts, je transmets également des valeurs telles qu'un nom d'utilisateur, la version de Fedora à mettre à niveau, des noms de fichiers, etc.

La possibilité d'utiliser des paramètres de position, également appelés arguments, pour spécifier les données à utiliser comme valeurs pour les variables dans les scripts est une méthode pour y parvenir. Une autre est l'utilisation d'options et d'arguments d'option. Cet article explore ces deux méthodes pour obtenir des données dans le script et contrôler le chemin d'exécution du script.

Paramètres de position

Bash utilise un outil appelé paramètres de position pour fournir un moyen d'entrer des données dans un programme Bash lorsqu'il est invoqué à partir de la ligne de commande. Il existe dix paramètres de position qui s'exécutent à partir de $0 jusqu'à 9 $ , bien qu'il existe des moyens de contourner cette limite.

À partir d'un simple script qui affiche un nom saisi à l'écran. Créez un fichier nommé script1.sh avec le contenu suivant et rendez-le exécutable.

#!/bin/bash
echo $0

J'ai placé ce script dans mon répertoire ~/bin directory , où les fichiers exécutables personnels tels que les scripts sont destinés à être stockés. Regardez votre $PATH variable, qui contient /home/username/bin comme un seul composant. Si le ~/bin directory répertoire n'existe pas, vous pouvez le créer. Ou vous pouvez simplement placer ce fichier où vous voulez et l'utiliser à partir de là.

Exécutez ensuite le script sans paramètres.

[student@testvm1 ~]$ script1.sh
/home/dboth/bin/script1.sh
[student@testvm1 ~]$

La sortie de ce script est le nom du script. Le 0 $ Le paramètre est réservé et prédéfini comme le nom du script en cours d'exécution et ne peut pas être utilisé à d'autres fins. Cela peut être pratique à l'intérieur d'un script car vous n'avez pas besoin de lui transmettre son propre nom s'il l'exige.

Alors changez le script pour utiliser $1 pour la variable de position, et exécutez-la à nouveau :

#!/bin/bash
echo $1

Exécutez-le à nouveau, cette fois en utilisant un seul paramètre :

[student@testvm1 ~]$ script1.sh help
help
[student@testvm1 ~]$

Que se passe-t-il si le paramètre est composé de deux mots ?

[student@testvm1 ~]$ script1.sh help me
help
[student@testvm1 ~]$

Il s'agit en fait de deux paramètres, mais vous pouvez y remédier avec des guillemets, comme illustré ici :

[student@testvm1 ~]$ script1.sh "help me"
help me
[student@testvm1 ~]$

Cela peut être utile lorsque l'entrée est censée être une adresse postale ou quelque chose avec plusieurs mots, comme ceci :

[student@testvm1 ~]$ script1.sh "80486 Intel St."
80486 Intel St.
[student@testvm1 ~]$

Mais il arrive parfois que vous ayez besoin de plusieurs paramètres, tels que des noms ou des adresses complètes.

Modifiez le programme pour qu'il ressemble à ceci :

#!/bin/bash
echo "Name: $1"
echo "Street: $2"
echo "City: $3"
echo "State/Province/Territory: $4"
echo "Zip/Postal code: $5"

Et exécutez-le en utilisant les paramètres comme indiqué :

[student@testvm1 ~]$ script1.sh "David Both" "80486 Intel St." Raleigh NC XXXXX
Name: David Both
Street: 80486 Intel St.
City: Raleigh
State/Province/Territory: NC
Zip/Postal code: XXXXX

Bien sûr, il existe de nombreuses façons d'utiliser les paramètres de position une fois les valeurs attribuées, mais ce petit programme permet de voir facilement ce qui se passe. Cela facilite également l'expérimentation en toute sécurité.

Essayez de mettre les paramètres dans un ordre différent pour voir comment cela fonctionne. Ces paramètres sont positionnels, et c'est une considération clé. Vous devez tenir compte du nombre de paramètres nécessaires, de la manière dont l'utilisateur s'en souvient et de l'ordre dans lequel les placer.

Vous avez besoin d'un moyen de rendre l'ordre des paramètres non pertinent et vous avez toujours besoin d'un moyen de modifier le chemin d'exécution.

Options

Vous pouvez faire ces deux choses en utilisant les options de ligne de commande.

Je trouve que même les programmes Bash simples devraient avoir une sorte de fonction d'aide, même si elle est assez rudimentaire. La plupart des programmes shell Bash que j'écris sont utilisés assez rarement pour que j'oublie la syntaxe exacte de la commande que je dois émettre. Certains sont tellement complexes que je dois revoir les options et les arguments nécessaires même si je les utilise fréquemment.

Le fait d'avoir une fonction d'aide intégrée vous permet de visualiser ces éléments sans avoir à inspecter le code lui-même. Une bonne et complète fonction d'aide fait également partie de la documentation du programme.

À propos des fonctions

Les fonctions shell sont des listes d'instructions de programme Bash stockées dans l'environnement du shell et peuvent être exécutées comme n'importe quelle autre commande en tapant son nom sur la ligne de commande. Les fonctions Shell peuvent également être appelées procédures ou sous-routines, selon l'autre langage de programmation que vous utilisez.

Les fonctions sont appelées dans vos scripts ou depuis la CLI à l'aide de leur nom, comme vous le feriez pour toute autre commande. Dans un programme CLI ou un script, les commandes de la fonction sont exécutées lorsqu'elles sont appelées. Ensuite, la séquence de flux de programme revient à l'entité appelante et la série suivante d'instructions de programme dans cette entité est exécutée.

La syntaxe d'une fonction est :

FunctionName(){instructions de programme}

Créez une fonction simple sur la CLI. La fonction est stockée dans l'environnement shell de l'instance shell dans laquelle elle est créée. Vous allez créer une fonction appelée hw , qui signifie Hello world . Entrez le code suivant dans la CLI et appuyez sur Entrée . Saisissez ensuite hw comme vous le feriez pour toute autre commande shell.

[student@testvm1 ~]$ hw(){ echo "Hi there kiddo"; }
[student@testvm1 ~]$ hw
Hi there kiddo
[student@testvm1 ~]$

Ok, donc je suis un peu fatigué du standard "Hello world!" Je commence généralement par. Répertoriez maintenant toutes les fonctions actuellement définies. Il y en a beaucoup, donc je n'ai montré que le nouveau hw une fonction. Lorsqu'elle est appelée depuis la ligne de commande ou dans un programme, une fonction exécute sa tâche programmée. Il quitte ensuite, rendant le contrôle à l'entité appelante, à la ligne de commande ou à l'instruction de programme Bash suivante dans un script après l'instruction appelante.

[student@testvm1 ~]$ declare -f | less
<snip>
hw ()
{
    echo "Hi there kiddo"
}
<snip>

Supprimez maintenant cette fonction car vous n'en avez plus besoin. Vous pouvez le faire avec le unset commande, comme ceci :

[student@testvm1 ~]$ unset -f hw ; hw
bash: hw: command not found
[student@testvm1 ~]$

Le script hello.sh

Créez un nouveau script shell Bash, ~/bin/hello.sh , et le rendre exécutable. Ajoutez le contenu suivant, en le gardant basique pour commencer :

#!/bin/bash
echo "hello world!"

Exécutez-le pour vérifier qu'il affiche "hello world !".

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$

Je sais - je ne peux pas m'en empêcher, alors je suis retourné à "hello world!".

Création de la fonction d'aide

Ajouter l'aide fonction ci-dessous au code du programme hello. Placez l'aide fonction entre les deux déclarations que vous avez déjà. Cette aide affichera une brève description du programme, un diagramme de syntaxe et une brève description de chaque option disponible. Vous ajoutez également un appel à l'aide fonction pour le tester et quelques lignes de commentaires qui fournissent une démarcation visuelle entre les fonctions et la partie principale du programme.

Le programme ressemble maintenant à ceci.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

Help
echo "Hello world!"

Les options décrites dans cette aide fonction pourrait être typique dans les programmes que j'écris, bien qu'aucune ne soit encore présente dans le code. Exécutez le programme pour le tester.

[student@testvm1 ~]$ hello.sh
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Hello world!
[student@testvm1 ~]$

Étant donné que vous n'avez ajouté aucune logique pour afficher l'aide lorsque vous le souhaitez, le programme affichera toujours l'aide. Cependant, vous savez que la fonction fonctionne correctement, vous pouvez donc ajouter une logique uniquement pour afficher l'aide lorsque vous utilisez un -h option à l'invocation de la ligne de commande du programme.

Options de gestion

La possibilité pour un script Bash de gérer les options de ligne de commande telles que -h pour afficher l'aide vous donne des capacités puissantes pour diriger le programme et modifier ce qu'il fait. Dans le cas de votre -h , vous voulez que le programme imprime le texte d'aide sur la session du terminal, puis quitte sans exécuter le reste du programme. La possibilité de traiter les options saisies sur la ligne de commande peut être ajoutée au script Bash en utilisant le while commande en conjonction avec getops et case commandes.

Les getops La commande lit toutes les options spécifiées sur la ligne de commande et crée une liste de ces options. Le while la commande parcourt la liste des options en définissant la variable $options pour chacun dans le code ci-dessous. Le case instruction est utilisée pour évaluer tour à tour chaque option et exécuter les instructions dans la strophe correspondante. Le while continue d'évaluer la liste des options jusqu'à ce qu'elles aient toutes été traitées ou qu'une instruction de sortie soit rencontrée, ce qui met fin au programme.

Assurez-vous de supprimer l'aide appel de fonction juste avant l'écho "Hello world!" pour que le corps principal du programme ressemble maintenant à ceci.

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
   esac
done

echo "Hello world!"

Remarquez le double point-virgule à la fin de l'instruction exit dans l'option case pour -h . Ceci est requis pour chaque option. Ajoutez à cette déclaration de cas pour délimiter la fin de chaque option.

Les tests sont maintenant un peu plus complexes. Vous devez tester votre programme avec plusieurs options différentes (et aucune option) pour voir comment il réagit. Tout d'abord, vérifiez que sans options, il imprime "Hello world!" comme il se doit.

[student@testvm1 ~]$ hello.sh
Hello world!

Cela fonctionne, alors testez maintenant la logique qui affiche le texte d'aide.

[student@testvm1 ~]$ hello.sh -h
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Cela fonctionne comme prévu, alors faites maintenant des tests pour voir ce qui se passe lorsque vous saisissez des options inattendues.

[student@testvm1 ~]$ hello.sh -x
Hello world!
[student@testvm1 ~]$ hello.sh -q
Hello world!
[student@testvm1 ~]$ hello.sh -lkjsahdf
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

[student@testvm1 ~]$

Gestion des options non valides

Le programme ignore simplement les options pour lesquelles vous n'avez pas créé de réponses spécifiques sans générer d'erreurs. Bien que dans la dernière entrée avec le -lkjsahdf options, car il y a un "h" dans la liste, le programme l'a reconnu et a imprimé le texte d'aide. Les tests ont montré qu'une chose qui manque est la capacité de gérer les entrées incorrectes et de terminer le programme si une entrée est détectée.

Vous pouvez ajouter une autre strophe case à l'instruction case qui correspondra à toute option pour laquelle il n'y a pas de correspondance explicite. Ce cas général correspondra à tout ce pour quoi vous n'avez pas fourni de correspondance spécifique. L'affaire l'instruction ressemble maintenant à ceci.

while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

Ce bout de code mérite une explication sur son fonctionnement. Cela semble complexe mais est assez facile à comprendre. Le pendant que – fait structure définit une boucle qui s'exécute une fois pour chaque option dans getopts – option structure. Le ":h" string — qui nécessite les guillemets — répertorie les options d'entrée possibles qui seront évaluées par le case – esac structure. Chaque option répertoriée doit avoir une strophe correspondante dans l'instruction case. Dans ce cas, il y en a deux. L'un est le h) strophe qui appelle la procédure d'aide. Une fois la procédure d'aide terminée, l'exécution revient à l'instruction de programme suivante, exit ;; qui sort du programme sans exécuter plus de code même s'il en existe. La boucle de traitement des options est également terminée, donc aucune option supplémentaire ne sera vérifiée.

Remarquez la correspondance fourre-tout de \ ? comme dernière strophe de l'instruction case. Si des options saisies ne sont pas reconnues, cette strophe imprime un court message d'erreur et quitte le programme.

Tout cas spécifique supplémentaire doit précéder le fourre-tout final. J'aime placer les strophes de cas par ordre alphabétique, mais il y aura des circonstances où vous voudrez vous assurer qu'un cas particulier est traité avant certains autres. L'instruction case est sensible à la séquence, soyez donc conscient de cela lorsque vous construisez la vôtre.

La dernière instruction de chaque strophe de la construction case doit se terminer par le double point-virgule (;; ), qui est utilisé pour marquer explicitement la fin de chaque strophe. Cela permet aux programmeurs qui aiment utiliser des points-virgules explicites pour la fin de chaque instruction au lieu d'implicites de continuer à le faire pour chaque instruction dans chaque strophe case.

Testez à nouveau le programme en utilisant les mêmes options qu'auparavant et voyez comment cela fonctionne maintenant.

Le script Bash ressemble maintenant à ceci.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello world!"

Assurez-vous de tester cette version de votre programme de manière très approfondie. Utilisez une entrée aléatoire et voyez ce qui se passe. Vous devriez également essayer de tester les options valides et invalides sans utiliser le tiret (- ) devant.

Utiliser les options pour saisir des données

Commencez par ajouter une variable et initialisez-la. Ajoutez les deux lignes indiquées en gras dans le segment du programme ci-dessous. Ceci initialise le $Name variable à "monde" par défaut.

<snip>
############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
<snip>

Changer la dernière ligne du programme, le echo commande, à ceci.

echo "hello $Name!"

Ajoutez la logique pour saisir un nom dans un instant, mais testez d'abord le programme à nouveau. Le résultat devrait être exactement le même qu'avant.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

$OPTARG est toujours le nom de variable utilisé pour chaque nouvel argument d'option, peu importe leur nombre. Vous devez attribuer la valeur dans $OPTARG à un nom de variable qui sera utilisé dans le reste du programme. Cette nouvelle strophe n'a pas d'instruction de sortie. Cela modifie le déroulement du programme de sorte qu'après avoir traité toutes les options valides dans l'instruction case, l'exécution passe à l'instruction suivante après la construction case.

Testez le programme révisé.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$ hello.sh -n LinuxGeek46
hello LinuxGeek46!
[dboth@david ~]$ hello.sh -n "David Both"
hello David Both!
[dboth@david ~]$

Le programme terminé ressemble à ceci.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello $Name!"

Assurez-vous de tester la fonction d'aide et la façon dont le programme réagit aux entrées invalides pour vérifier que sa capacité à les traiter n'a pas été compromise. Si tout fonctionne comme il se doit, alors vous avez appris à utiliser les options et les arguments d'option.

[ Obtenez cet ebook gratuit :Gérer vos clusters Kubernetes pour les nuls. ]

Récapitulez

Dans cet article, vous avez utilisé des paramètres de position pour entrer des données dans le programme Bash lors de l'invocation à partir de la ligne de commande et utilisé des options pour diriger le flux du programme ainsi que pour entrer des données dans le programme. Vous avez ajouté une fonction d'aide et la possibilité de traiter les options de ligne de commande pour afficher l'aide de manière sélective. Et vous avez ajouté un argument facultatif qui permet de saisir un nom sur la ligne de commande.

Ce petit programme de test est conçu pour être simple, vous pouvez donc facilement l'expérimenter vous-même pour tester cette méthode de saisie par vous-même. A titre d'exercice, révisez le programme pour prendre un prénom et un nom de famille. Essayez d'entrer les options pour les noms et prénoms dans l'ordre inverse pour voir ce qui se passe.

Ressources

  • Comment programmer avec Bash :syntaxe et outils
  • Comment programmer avec Bash :opérateurs logiques et extensions du shell
  • Comment programmer avec Bash :Boucles

Linux
  1. Dans Bash, quand créer un alias, quand créer un script et quand écrire une fonction ?

  2. Passer les arguments de la ligne de commande au script Bash ?

  3. Comment mettre en surbrillance les scripts Bash dans Vim ?

  4. Comment passer des paramètres à un script Bash ?

  5. automatiser la session telnet à l'aide de scripts bash

Bash-it - Framework Bash pour contrôler vos scripts et alias

Comment déboguer les scripts Bash sous Linux et Unix

Bash Scripting - Analyser les arguments dans les scripts Bash à l'aide de getopts

Bash Beginner Series #1 :Créez et exécutez votre premier script shell Bash

Bash Beginner Series #3 :Passer des arguments aux scripts Bash

Arguments Pycharm et sys.argv