arguments bas. BASH : analyse des options de ligne de commande. Lire les données d'un fichier

getopts est une commande Bash intégrée utilisée pour analyser les arguments passés à un script à partir de la ligne de commande. Il vous permet de traiter une série d'options combinées en un seul argument et des arguments supplémentaires passés par l'option.

# nom_script -abc -d /home/utilisateur

Les variables cachées utilisées avec la commande getopts sont $OPTIND et $OPTARG.

Un caractère deux-points après un nom d'option indique qu'il a un argument facultatif.

Tandis que getopts ":abcde:fg" Option

En règle générale, getopts est enveloppé dans une boucle while, chaque itération de la boucle récupérant l'option suivante et son argument (le cas échéant), le traitant, puis décrémentant la variable cachée $OPTIND de 1 et sautant au début d'une nouvelle itération.

Les options transmises à un script depuis la ligne de commande doivent être précédées d'un signe moins (-) ou d'un signe plus (+). Ce préfixe (- ou +) permet à getopts de distinguer les options des autres arguments. En fait, getopts ne traitera pas les arguments à moins qu'ils ne soient précédés d'un - ou d'un +, et l'extraction des options s'arrêtera dès que le premier argument sera rencontré.

La construction typique d'une boucle while avec getopts est légèrement différente de celle standard en raison de l'absence de crochets qui vérifient la condition de poursuite de la boucle.
Vous pouvez voir comment getopts fonctionne avec le script suivant.

test-getopts

usage()(
echo "Le script `basename $0` sert à démontrer la puissance de getopts."
écho ""
echo "Utilisation : `basename $0` -abef -c C -d D"
echo -e » \033 # Script appelé sans arguments ?
alors
usage # Si exécuté sans arguments, affiche l'aide
exit $E_OPTERROR # et sortie avec un code d'erreur
Fi

tandis que l'option getops "abc:d:ef"
faire
cas $Option dans
un | b) echo "Action 1 : l'option est $Option. Numéro d'option : $OPTIND. Argument : $OPTARG";;
c) echo "Action 2 : option - $Option. Numéro d'option : $OPTIND. Argument : $OPTARG";;
d) echo "Action 3 : option - $Option. Numéro d'option : $OPTIND. Argument : $OPTARG";;
e) echo "Action 4 : option - $Option. Numéro d'option : $OPTIND. Argument : $OPTARG";;
f) echo "Action 5 : option - $Option. Numéro d'option : $OPTIND. Argument : $OPTARG";;
*) echo "Clé invalide sélectionnée."
usage
exit $E_OPTERROR;; # DÉFAUT
esac
fait
décalage $(($OPTIND - 1))

Essayez de l'exécuter comme ceci :

test-getopts -abc avec -opt
test-getopts -abefd d-opt

Et maintenant comme ça :

Test-getopts -abcdef
test-getopts -cd d-opt

Ce comportement de getopts est dû au fait que l'option -c attend un argument supplémentaire.

Tout le monde sait que le shell Bash contient des commandes intégrées qui ne se trouvent pas dans les dossiers /bin ou /usr/bin. Ils sont intégrés au shell et exécutés en tant que fonctions. Dans l'un des articles précédents, nous avons considéré. Nous avons discuté de presque tout là-bas, à quoi les scripts devraient ressembler, l'utilisation de conditions, de boucles, de variables, mais nous ne nous sommes pas arrêtés aux fonctions.

Dans l'article d'aujourd'hui, nous corrigerons cette lacune. Comme tout langage de programmation, Bash possède des fonctions qui peuvent être très utiles à utiliser. Nous verrons comment utiliser les fonctions bash, comment les écrire et même comment créer des bibliothèques à partir de ces fonctions.

Nous devons d'abord comprendre ce qu'est une fonction dans notre contexte. Une fonction est un ensemble de commandes, unies par un nom, qui exécutent une tâche spécifique. La fonction est appelée par son nom, peut prendre des paramètres et retourner le résultat du travail. En bref, les fonctions Bash fonctionnent exactement comme dans d'autres langages de programmation.

La syntaxe pour créer une fonction est très simple :

nom_fonction() ( liste de commandes )

Le nom de la fonction ne doit correspondre à aucune des commandes ou fonctions existantes, et toutes les commandes du corps de la fonction sont écrites sur une nouvelle ligne.

fonction simple

Écrivons une petite fonction qui affichera une chaîne à l'écran :

$ vi fonction.sh

#!/bin/bash
printstr()(
echo "bonjour le monde"
}
printstr

L'appel d'une fonction bash se fait en spécifiant son nom, comme pour toute autre commande. Lancez notre script pour exécution, n'oubliez pas qu'avant cela vous devez lui donner les droits d'exécution :

chmod u+x fonction.sh

Tout fonctionne, maintenant compliquons la tâche, essayons de passer des arguments à la fonction.

Arguments de la fonction

Les arguments de fonction doivent être passés lors de l'appel et ils sont lus de la même manière que les arguments de script. La syntaxe pour appeler une fonction avec des paramètres bash est :

nom_fonction argument1 argument2 ... argumentN

Comme vous pouvez le voir, tout est assez simple. Les paramètres sont séparés par un espace. Améliorons maintenant notre fonction afin qu'elle renvoie la chaîne que nous avons spécifiée :

!/bin/bas
printstr()(
écho $1
}
printstr "Bonjour le monde"

Vous pouvez avoir plusieurs options :

!/bin/bas
printstr()(
écho $1
écho $2
écho $3
écho $5
}
printstr "arg1" "arg2" "arg3" "arg4" "arg5"

Il existe une autre façon d'extraire des arguments, comme en C, en utilisant la pile. Nous récupérons le premier argument, puis avançons le pointeur de pile d'arguments de un, et récupérons à nouveau le premier argument. Et ainsi de suite:

!/bin/bas
printstr()(
écho $1
changement
écho $1
changement
écho $1
changement
écho $1
}
printstr "arg1" "arg2" "arg3" "arg4"

Renvoyer le résultat d'une fonction

Vous pouvez non seulement utiliser des fonctions avec des paramètres bash, mais également en obtenir le résultat. La commande return est utilisée pour cela. Il termine la fonction et renvoie la valeur numérique du code de retour. Il peut être compris entre 0 et 255 :

!/bin/bas
printstr()(
retour 134;
}
printstr
echo $?

Si vous devez utiliser la valeur de retour d'une fonction bash plutôt que le code d'état, utilisez echo. La chaîne n'est pas immédiatement envoyée au terminal, mais est renvoyée comme résultat de la fonction et peut être écrite dans une variable puis utilisée :

!/bin/bas
printstr()(
écho "tester"
}
VAR=$(printstr)
écho $VAR

Fonctions d'exportation

Vous pouvez rendre une fonction disponible en dehors d'un script avec la commande declare :

!/bin/bas
printstr()(
echo "bonjour le monde"
}
déclarer -x -f printstr

Exécutez ensuite le script avec la commande source :

fonction source.sh
$printstr

récursivité

Vous pouvez appeler une fonction depuis elle-même pour effectuer la récursivité :

!/bin/bas
printstr()(
echo "bonjour le monde"
printstr
}
printstr

Vous pouvez expérimenter l'utilisation de la récursivité, cela peut être utile dans de nombreux cas, n'oubliez pas de faire le premier appel de la fonction Bash.

Variables locales dans une fonction

Si vous déclarez une variable ordinaire dans une fonction, alors elle sera disponible dans tout le script, c'est pratique pour retourner la valeur de la fonction, mais parfois il peut être nécessaire d'en faire une variable locale. Il existe une commande locale pour cela :

!/bin/bas
printstr()(
VAR locale=$1
echo $(var)
}
printstr "Bonjour le monde"

Bibliothèques de fonctions

Nous pouvons prendre certaines fonctions bash et les combiner dans une bibliothèque afin de pouvoir importer ces fonctions avec une seule commande. Cela se fait de la même manière que pour exporter des fonctions. Commençons par créer un fichier de bibliothèque :

essai1()(
echo "Bonjour le monde de 1" ;
}
essai2()(
echo "Bonjour le monde de 2" ;
}
essai3()(
echo "Hello World from 3" ;
}

Créons maintenant un script qui utilisera nos fonctions. Vous pouvez importer la bibliothèque à l'aide de la commande source ou en spécifiant simplement le nom du script :

!/bin/bas
source lib.sh
test1
test2
test3

conclusions

Dans cet article, nous avons examiné les fonctions bash, comment les écrire, les appliquer et les combiner dans des bibliothèques. Si vous écrivez souvent des scripts dans Bash, ces informations vous seront utiles. Vous pouvez créer votre propre ensemble de fonctions à utiliser dans chaque script et ainsi faciliter votre travail.

Après avoir maîtrisé les parties précédentes de cette série de documents, vous avez appris ce que sont les scripts bash, comment les écrire, comment contrôler le flux d'exécution du programme, comment travailler avec des fichiers. Aujourd'hui, nous allons parler de la façon d'ajouter de l'interactivité aux scripts en les dotant de la capacité de recevoir des données de l'utilisateur et de traiter ces données.

La façon la plus courante de transmettre des données aux scripts consiste à utiliser les options de ligne de commande. En appelant le script avec des paramètres, nous lui transmettons des informations avec lesquelles il peut fonctionner. Il ressemble à ceci :

$ ./monscript 10 20
Dans cet exemple, deux paramètres sont passés au script - "10" et "20". Tout cela est bien, mais comment lire les données dans le script ?

Lecture des options de ligne de commande

Le shell bash affecte des variables spéciales appelées paramètres de position aux paramètres de ligne de commande saisis lors de l'appel du script :
  • $0 - nom du script.
  • $1 est le premier paramètre.
  • $2 est le deuxième paramètre - et ainsi de suite, jusqu'à $9 , qui est le neuvième paramètre.
Voici comment vous pouvez utiliser les options de ligne de commande dans un script avec ces variables :

#!/bin/bash echo $0 echo $1 echo $2 echo $3
Exécutons le script avec des paramètres :

./monscript 5 10 15
C'est ce qu'il affichera sur la console.


Affichage des paramètres avec lesquels le script a été lancé

Notez que les options de ligne de commande sont séparées par des espaces.

Regardons un autre exemple d'utilisation de paramètres. On retrouve ici la somme des nombres passés au script :

#!/bin/bash total=$[ $1 + $2 ] echo Le premier paramètre est $1. echo Le deuxième paramètre est $2. echo La somme est $total.
Exécutons le script et vérifions le résultat du calcul.


Script qui trouve la somme des nombres qui lui sont passés

Les options de la ligne de commande ne doivent pas nécessairement être des nombres. Vous pouvez également transmettre des chaînes aux scripts. Par exemple, voici un script qui fonctionne avec une chaîne :

#!/bin/bash echo Bonjour $1, comment allez-vous
Exécutons-le :

./monscript Adam
Il affichera ce que nous attendons de lui.


Script qui fonctionne avec un paramètre de chaîne

Que se passe-t-il si le paramètre contient des espaces et que nous devons le traiter comme une donnée indépendante ? Nous pensons que si vous avez maîtrisé les parties précédentes de ce guide, vous connaissez déjà la réponse. Il consiste en l'utilisation de guillemets.

Si le script a besoin de plus de neuf paramètres, lors de l'accès à ceux-ci, le nombre dans le nom de la variable doit être entouré d'accolades, comme ceci :

Vérification des paramètres

Si le script est appelé sans paramètres, mais que leur présence est attendue pour le fonctionnement normal du code, une erreur se produira. Par conséquent, il est recommandé de toujours vérifier la présence de paramètres passés au script lors de son appel. Par exemple, il pourrait être organisé comme ceci :

#!/bin/bash if [ -n "$1" ] then echo Hello $1. sinon echo "Aucun paramètre trouvé." fi
Appelons d'abord le script avec un paramètre, puis sans paramètre.


Appel d'un script qui vérifie les options de ligne de commande

Nombre de paramètres

Dans un script, vous pouvez compter le nombre de paramètres qui lui sont transmis. Le shell bash fournit une variable spéciale pour cela. A savoir, la variable $# contient le nombre de paramètres passés au script lors de son appel.

Essayons-le :

#!/bin/bash echo Il y avait $# paramètres passés.
Appelons le script.

./monscript 1 2 3 4 5
En conséquence, le script signalera que 5 paramètres lui ont été transmis.


Compter le nombre de paramètres dans un script

Cette variable fournit un moyen inhabituel d'obtenir le dernier des paramètres transmis au script, sans nécessiter la connaissance de leur nombre. Voici à quoi ça ressemble :

#!/bin/bash echo Le dernier paramètre était $(!#)
Appelons le script et voyons ce qu'il affiche.


Accéder au dernier paramètre

Capture de toutes les options de ligne de commande

Dans certains cas, vous devez capturer tous les paramètres passés au script. Pour ce faire, vous pouvez utiliser les variables $* et [courriel protégé]. Les deux contiennent toutes les options de ligne de commande, ce qui permet d'accéder à ce qui est passé au script sans utiliser de paramètres de position.

La variable $* contient toutes les options saisies sur la ligne de commande sous la forme d'un seul "mot".

Dans une variable [courriel protégé] les paramètres sont divisés en "mots" séparés. Ces paramètres peuvent être itérés par cycles.

Regardons la différence entre ces variables avec des exemples. Voyons d'abord leur contenu :

#!/bin/bash echo "En utilisant la méthode \$* : $*" echo "-----------" echo "En utilisant la méthode \ [courriel protégé] méthode: [courriel protégé]"
Voici la sortie du script.


Variables $* et [courriel protégé]

Comme vous pouvez le voir, la sortie des deux variables donne le même résultat. Essayons maintenant de parcourir le contenu de ces variables afin de voir la différence entre elles :

#!/bin/bash count=1 for param in "$*" do echo "\$* Parameter #$count = $param" count=$(($count + 1)) done count=1 for param in " [courriel protégé]" faire écho "\ [courriel protégé] Paramètre #$count = $param" count=$(($count + 1)) fait
Jetez un œil à ce que le script a imprimé sur la console. La différence entre les variables est assez évidente.


Analyse variable $* et [courriel protégé] en cycle

La variable $* contient tous les paramètres passés au script sous la forme d'une seule donnée, tandis que dans la variable [courriel protégé] ils sont représentés par des valeurs indépendantes. La variable à utiliser dépend de ce qui est exactement nécessaire dans un scénario particulier.

commande de décalage

La commande shift doit être utilisée avec prudence dans les scripts bash, car elle décale littéralement les valeurs des paramètres positionnels.

Lorsque vous utilisez cette commande, elle déplace par défaut les valeurs des paramètres positionnels vers la gauche. Par exemple, la valeur de la variable $3 devient la valeur de la variable $2 , la valeur de $2 devient $1 et ce qui était auparavant dans $1 est perdu. Notez que cela ne change pas la valeur de la variable $0 contenant le nom du script.

En utilisant la commande shift, considérons une autre façon d'itérer sur les paramètres passés au script :

#!/bin/bash count=1 while [ -n "$1" ] do echo "Paramètre #$count = $1" count=$(($count + 1)) shift done
Le script utilise une boucle while, vérifiant la longueur de la valeur du premier paramètre. Lorsque la longueur devient nulle, la boucle se termine. Après avoir vérifié le premier paramètre et l'avoir affiché à l'écran, la commande de décalage est appelée, ce qui décale les valeurs des paramètres d'une position.


Utilisation de la commande shift pour parcourir les options

Lorsque vous utilisez la commande shift, rappelez-vous qu'à chaque fois qu'elle est appelée, la valeur de $1 est irrémédiablement perdue.

Commutateurs de ligne de commande

Les commutateurs de ligne de commande ressemblent généralement à des lettres précédées d'un tiret. Ils servent à gérer les scénarios. Considérez cet exemple :

#!/bin/bash echo while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a" ;; -b) echo "L'option -b a été trouvée" ;; -c) echo "L'option -c a été trouvée" ;; *) echo "$1 n'est pas une option" ;; décalage esac terminé
Exécutons le script :

$ ./monscript -a -b -c -d
Et analysons ce qu'il affichera sur le terminal.


Manipuler les clés dans un script

Ce code utilise la construction case, qui vérifie la clé qui lui est transmise par rapport à la liste des clés traitées par le script. Si la valeur passée est trouvée dans cette liste, la branche de code correspondante est exécutée. Si une touche quelconque est utilisée lors de l'appel du script dont le traitement n'est pas prévu, la branche "*" sera exécutée.

Comment faire la distinction entre les clés et les paramètres

Souvent, lors de l'écriture de scripts bash, une situation se produit lorsque vous devez utiliser à la fois des options de ligne de commande et des commutateurs. La méthode standard consiste à utiliser une séquence de caractères spéciale qui indique au script la fin des touches et le début des options normales.

Cette séquence est un double tiret (--). Le shell l'utilise pour indiquer la position à laquelle se termine la liste des clés. Une fois que le script a détecté le signe de la fin des clés, ce qui reste peut être traité comme des paramètres, et non comme des clés, sans crainte d'erreurs. Prenons un exemple :

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a" ;; -b) echo "L'option -b a été trouvée" ;; -c) echo "L'option -c a été trouvée" ;; --) pause changement ;; *) echo "$1 n'est pas une option";; esac shift done count=1 for param in [courriel protégé] do echo "Paramètre #$count : $param" count=$(($count + 1)) done
Ce script utilise la commande break pour rompre la boucle while lorsqu'il rencontre un double tiret dans une chaîne.

Voici ce qui se passe après l'avoir appelé.


Gestion des commutateurs et des options de ligne de commande

Comme vous pouvez le voir, lorsque le script, analysant les données qui lui sont transmises, trouve un double tiret, il termine le traitement des clés et considère tout ce qui n'a pas encore été traité comme des paramètres.

Gestion des clés avec des valeurs

Au fur et à mesure que vos scripts deviennent plus complexes, vous rencontrerez des situations où les clés régulières ne suffisent plus, ce qui signifie que vous devrez utiliser des clés avec certaines valeurs. Par exemple, un appel de script utilisant cette fonctionnalité ressemble à ceci :

./monscript -a test1 -b -c test2
Le script doit être capable de détecter quand des options supplémentaires sont utilisées avec les options de ligne de commande :

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a";; -b) param="$2" echo "L'option -b a été trouvée, avec la valeur de paramètre $param" shift ;; -c) echo "L'option -c a été trouvée" ;; --) pause changement ;; *) echo "$1 n'est pas une option";; esac shift done count=1 for param in " [courriel protégé]" do echo "Paramètre #$count : $param" count=$(($count + 1)) done
Appelons ce script comme ceci :

./monscript -a -b test1 -d
Voyons les résultats de son travail.


Gestion des paramètres clés

Dans cet exemple, trois clés sont traitées dans la construction case. Le commutateur -b nécessite un paramètre supplémentaire. Puisque la clé en cours de traitement est dans la variable $1, son paramètre correspondant sera dans $2 (la commande shift est utilisée ici, donc pendant qu'elle est traitée, tout ce qui est passé au script est décalé vers la gauche). Lorsque nous avons traité cela, il ne reste plus qu'à extraire la valeur de la variable $2 et nous aurons le paramètre de la clé souhaitée. Bien sûr, une autre commande shift est nécessaire ici pour que la clé suivante entre dans $1 .

Utilisation des clés standard

Lors de l'écriture de scripts bash, vous pouvez choisir n'importe quelle lettre pour les commutateurs de ligne de commande et définir arbitrairement la réaction du script à ces commutateurs. Cependant, dans le monde Linux, les valeurs de certaines clés sont devenues une sorte de norme qu'il est utile de respecter. Voici une liste de ces clés :
-a Affiche tous les objets.
-c Effectue un comptage.
-d Spécifie un répertoire.
-e Développer l'objet.
-f Spécifiez le fichier à partir duquel lire les données.
-h Affiche l'aide de la commande.
-i Ignorer la casse.
-l Effectue une sortie plein format.
-n Utiliser le mode non interactif (batch).
-o Vous permet de spécifier le fichier vers lequel vous souhaitez rediriger la sortie.
-q Exécute le script en mode silencieux.
-r Traite les dossiers et les fichiers de manière récursive.
-s Exécute le script en mode silencieux.
-v Exécute une sortie détaillée.
-x Exclure l'objet.
-y Répondre "oui" à toutes les questions.

Si vous utilisez Linux, vous connaissez probablement bon nombre de ces clés. En les utilisant dans leur sens conventionnel dans vos scripts, vous aiderez les utilisateurs à interagir avec eux sans avoir à vous soucier de la lecture de la documentation.

Obtenir des données de l'utilisateur

Les commutateurs et les options de la ligne de commande sont un excellent moyen d'obtenir des informations de la part de l'utilisateur du script, mais dans certains cas, une plus grande interactivité est nécessaire.

Parfois, les scripts ont besoin de données que l'utilisateur doit saisir pendant l'exécution du programme. Le shell bash fournit la commande de lecture dans ce but précis.

Cette commande vous permet d'accepter l'entrée soit à partir de l'entrée standard (du clavier), soit à l'aide d'autres descripteurs de fichier. Après avoir récupéré les données, cette commande les place dans une variable :

#!/bin/bash echo -n "Entrez votre nom : " read name echo "Bonjour $name, bienvenue dans mon programme."
Notez que la commande echo, qui imprime l'invite, est invoquée avec l'option -n. Cela se traduit par aucun saut de ligne à la fin de l'invite, ce qui permet à l'utilisateur du script d'entrer des données au même emplacement que l'invite plutôt que sur la ligne suivante.


Gestion des entrées utilisateur

Lors de l'appel de read, vous pouvez spécifier plusieurs variables :

#!/bin/bash read -p "Entrez votre nom : " first last echo "Vos données pour $last, $first…"
C'est ce que le script affichera lors de son exécution.


Plusieurs variables dans la commande de lecture

Si aucune variable n'est spécifiée lors de l'appel de read , les données saisies par l'utilisateur seront placées dans la variable d'environnement spéciale REPLY :

#!/bin/bash read -p "Entrez votre nom : " echo Bonjour $REPLY, bienvenue dans mon programme.


Utilisation de la variable d'environnement REPLY

Si le script doit continuer à s'exécuter, que l'utilisateur saisisse ou non des données, vous pouvez utiliser le commutateur -t lors de l'appel de la commande de lecture. À savoir, le paramètre clé définit le temps d'attente d'entrée en secondes :

#!/bin/bash if read -t 5 -p "Entrez votre nom : " name then echo "Bonjour $nom, bienvenue dans mon script" else echo "Désolé, trop lent !" fi
Si les données ne sont pas entrées dans les 5 secondes, le script exécutera la branche else de l'instruction conditionnelle, en imprimant des excuses.


Délai de saisie des données

Saisie des mots de passe

Parfois, ce que l'utilisateur entre en réponse à la question du script est préférable de ne pas être affiché à l'écran. Par exemple, cela se fait généralement lors de la demande de mots de passe. L'option -s de la commande read empêche l'affichage des entrées au clavier à l'écran. En fait, les données sont sorties, mais la commande de lecture rend la couleur du texte identique à la couleur d'arrière-plan.

#!/bin/bash read -s -p "Entrez votre mot de passe : " pass echo "Votre mot de passe est-il vraiment $pass ?"
Voici comment ce script fonctionnera.


Saisie de données sensibles

Lire les données d'un fichier

La commande de lecture peut, à chaque appel, lire une ligne de texte dans un fichier. Lorsqu'il ne reste plus de lignes non lues dans le fichier, il s'arrête simplement. Si vous avez besoin d'obtenir tout le contenu d'un fichier dans un script, vous pouvez diriger les résultats de l'appel de la commande cat sur le fichier vers la construction while, qui contient la commande read (bien sûr, l'utilisation de la commande cat semble primitive, mais notre objectif est de tout montrer le plus simplement possible, en nous concentrant sur les débutants ; les utilisateurs expérimentés comprendront certainement cela).

Écrivons un script qui utilise l'approche décrite ci-dessus pour lire les fichiers.

#!/bin/bash count=1 chat monfichier | while read line do echo "Ligne $count: $line" count=$(($count + 1)) done echo "Terminé"
Voyons-le en action.


Lire les données d'un fichier

Ici, nous avons passé le contenu du fichier à la boucle while et parcouru toutes les lignes de ce fichier, en affichant le nombre et le contenu de chacune d'entre elles.

Résultats

Aujourd'hui, nous avons analysé le travail avec les commutateurs et les paramètres de ligne de commande. Sans ces outils, le champ d'utilisation des scripts est extrêmement restreint. Même si le scénario est écrit, comme on dit, "pour moi". Là, nous avons envisagé des approches pour recevoir des données de l'utilisateur lors de l'exécution du programme - cela rend les scripts interactifs.

La prochaine fois, nous parlerons des opérations d'entrée et de sortie.

Chers lecteurs! Merci de partager votre expérience dans les commentaires sur les parties précédentes de cette série de documents. Si vous avez quelque chose à dire sur la gestion de tout ce qui peut être transmis à un script au démarrage ou pendant son exécution, nous sommes sûrs que beaucoup seront intéressés à en savoir plus.

Après avoir maîtrisé les parties précédentes de cette série de documents, vous avez appris ce que sont les scripts bash, comment les écrire, comment contrôler le flux d'exécution du programme, comment travailler avec des fichiers. Aujourd'hui, nous allons parler de la façon d'ajouter de l'interactivité aux scripts en les dotant de la capacité de recevoir des données de l'utilisateur et de traiter ces données.

La façon la plus courante de transmettre des données aux scripts consiste à utiliser les options de ligne de commande. En appelant le script avec des paramètres, nous lui transmettons des informations avec lesquelles il peut fonctionner. Il ressemble à ceci :

$ ./monscript 10 20
Dans cet exemple, deux paramètres sont passés au script - "10" et "20". Tout cela est bien, mais comment lire les données dans le script ?

Lecture des options de ligne de commande

Le shell bash affecte des variables spéciales appelées paramètres de position aux paramètres de ligne de commande saisis lors de l'appel du script :
  • $0 - nom du script.
  • $1 est le premier paramètre.
  • $2 est le deuxième paramètre - et ainsi de suite, jusqu'à $9 , qui est le neuvième paramètre.
Voici comment vous pouvez utiliser les options de ligne de commande dans un script avec ces variables :

#!/bin/bash echo $0 echo $1 echo $2 echo $3
Exécutons le script avec des paramètres :

./monscript 5 10 15
C'est ce qu'il affichera sur la console.


Affichage des paramètres avec lesquels le script a été lancé

Notez que les options de ligne de commande sont séparées par des espaces.

Regardons un autre exemple d'utilisation de paramètres. On retrouve ici la somme des nombres passés au script :

#!/bin/bash total=$[ $1 + $2 ] echo Le premier paramètre est $1. echo Le deuxième paramètre est $2. echo La somme est $total.
Exécutons le script et vérifions le résultat du calcul.


Script qui trouve la somme des nombres qui lui sont passés

Les options de la ligne de commande ne doivent pas nécessairement être des nombres. Vous pouvez également transmettre des chaînes aux scripts. Par exemple, voici un script qui fonctionne avec une chaîne :

#!/bin/bash echo Bonjour $1, comment allez-vous
Exécutons-le :

./monscript Adam
Il affichera ce que nous attendons de lui.


Script qui fonctionne avec un paramètre de chaîne

Que se passe-t-il si le paramètre contient des espaces et que nous devons le traiter comme une donnée indépendante ? Nous pensons que si vous avez maîtrisé les parties précédentes de ce guide, vous connaissez déjà la réponse. Il consiste en l'utilisation de guillemets.

Si le script a besoin de plus de neuf paramètres, lors de l'accès à ceux-ci, le nombre dans le nom de la variable doit être entouré d'accolades, comme ceci :

Vérification des paramètres

Si le script est appelé sans paramètres, mais que leur présence est attendue pour le fonctionnement normal du code, une erreur se produira. Par conséquent, il est recommandé de toujours vérifier la présence de paramètres passés au script lors de son appel. Par exemple, il pourrait être organisé comme ceci :

#!/bin/bash if [ -n "$1" ] then echo Hello $1. sinon echo "Aucun paramètre trouvé." fi
Appelons d'abord le script avec un paramètre, puis sans paramètre.


Appel d'un script qui vérifie les options de ligne de commande

Nombre de paramètres

Dans un script, vous pouvez compter le nombre de paramètres qui lui sont transmis. Le shell bash fournit une variable spéciale pour cela. A savoir, la variable $# contient le nombre de paramètres passés au script lors de son appel.

Essayons-le :

#!/bin/bash echo Il y avait $# paramètres passés.
Appelons le script.

./monscript 1 2 3 4 5
En conséquence, le script signalera que 5 paramètres lui ont été transmis.


Compter le nombre de paramètres dans un script

Cette variable fournit un moyen inhabituel d'obtenir le dernier des paramètres transmis au script, sans nécessiter la connaissance de leur nombre. Voici à quoi ça ressemble :

#!/bin/bash echo Le dernier paramètre était $(!#)
Appelons le script et voyons ce qu'il affiche.


Accéder au dernier paramètre

Capture de toutes les options de ligne de commande

Dans certains cas, vous devez capturer tous les paramètres passés au script. Pour ce faire, vous pouvez utiliser les variables $* et [courriel protégé]. Les deux contiennent toutes les options de ligne de commande, ce qui permet d'accéder à ce qui est passé au script sans utiliser de paramètres de position.

La variable $* contient toutes les options saisies sur la ligne de commande sous la forme d'un seul "mot".

Dans une variable [courriel protégé] les paramètres sont divisés en "mots" séparés. Ces paramètres peuvent être itérés par cycles.

Regardons la différence entre ces variables avec des exemples. Voyons d'abord leur contenu :

#!/bin/bash echo "En utilisant la méthode \$* : $*" echo "-----------" echo "En utilisant la méthode \ [courriel protégé] méthode: [courriel protégé]"
Voici la sortie du script.


Variables $* et [courriel protégé]

Comme vous pouvez le voir, la sortie des deux variables donne le même résultat. Essayons maintenant de parcourir le contenu de ces variables afin de voir la différence entre elles :

#!/bin/bash count=1 for param in "$*" do echo "\$* Parameter #$count = $param" count=$(($count + 1)) done count=1 for param in " [courriel protégé]" faire écho "\ [courriel protégé] Paramètre #$count = $param" count=$(($count + 1)) fait
Jetez un œil à ce que le script a imprimé sur la console. La différence entre les variables est assez évidente.


Analyse variable $* et [courriel protégé] en cycle

La variable $* contient tous les paramètres passés au script sous la forme d'une seule donnée, tandis que dans la variable [courriel protégé] ils sont représentés par des valeurs indépendantes. La variable à utiliser dépend de ce qui est exactement nécessaire dans un scénario particulier.

commande de décalage

La commande shift doit être utilisée avec prudence dans les scripts bash, car elle décale littéralement les valeurs des paramètres positionnels.

Lorsque vous utilisez cette commande, elle déplace par défaut les valeurs des paramètres positionnels vers la gauche. Par exemple, la valeur de la variable $3 devient la valeur de la variable $2 , la valeur de $2 devient $1 et ce qui était auparavant dans $1 est perdu. Notez que cela ne change pas la valeur de la variable $0 contenant le nom du script.

En utilisant la commande shift, considérons une autre façon d'itérer sur les paramètres passés au script :

#!/bin/bash count=1 while [ -n "$1" ] do echo "Paramètre #$count = $1" count=$(($count + 1)) shift done
Le script utilise une boucle while, vérifiant la longueur de la valeur du premier paramètre. Lorsque la longueur devient nulle, la boucle se termine. Après avoir vérifié le premier paramètre et l'avoir affiché à l'écran, la commande de décalage est appelée, ce qui décale les valeurs des paramètres d'une position.


Utilisation de la commande shift pour parcourir les options

Lorsque vous utilisez la commande shift, rappelez-vous qu'à chaque fois qu'elle est appelée, la valeur de $1 est irrémédiablement perdue.

Commutateurs de ligne de commande

Les commutateurs de ligne de commande ressemblent généralement à des lettres précédées d'un tiret. Ils servent à gérer les scénarios. Considérez cet exemple :

#!/bin/bash echo while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a" ;; -b) echo "L'option -b a été trouvée" ;; -c) echo "L'option -c a été trouvée" ;; *) echo "$1 n'est pas une option" ;; décalage esac terminé
Exécutons le script :

$ ./monscript -a -b -c -d
Et analysons ce qu'il affichera sur le terminal.


Manipuler les clés dans un script

Ce code utilise la construction case, qui vérifie la clé qui lui est transmise par rapport à la liste des clés traitées par le script. Si la valeur passée est trouvée dans cette liste, la branche de code correspondante est exécutée. Si une touche quelconque est utilisée lors de l'appel du script dont le traitement n'est pas prévu, la branche "*" sera exécutée.

Comment faire la distinction entre les clés et les paramètres

Souvent, lors de l'écriture de scripts bash, une situation se produit lorsque vous devez utiliser à la fois des options de ligne de commande et des commutateurs. La méthode standard consiste à utiliser une séquence de caractères spéciale qui indique au script la fin des touches et le début des options normales.

Cette séquence est un double tiret (--). Le shell l'utilise pour indiquer la position à laquelle se termine la liste des clés. Une fois que le script a détecté le signe de la fin des clés, ce qui reste peut être traité comme des paramètres, et non comme des clés, sans crainte d'erreurs. Prenons un exemple :

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a" ;; -b) echo "L'option -b a été trouvée" ;; -c) echo "L'option -c a été trouvée" ;; --) pause changement ;; *) echo "$1 n'est pas une option";; esac shift done count=1 for param in [courriel protégé] do echo "Paramètre #$count : $param" count=$(($count + 1)) done
Ce script utilise la commande break pour rompre la boucle while lorsqu'il rencontre un double tiret dans une chaîne.

Voici ce qui se passe après l'avoir appelé.


Gestion des commutateurs et des options de ligne de commande

Comme vous pouvez le voir, lorsque le script, analysant les données qui lui sont transmises, trouve un double tiret, il termine le traitement des clés et considère tout ce qui n'a pas encore été traité comme des paramètres.

Gestion des clés avec des valeurs

Au fur et à mesure que vos scripts deviennent plus complexes, vous rencontrerez des situations où les clés régulières ne suffisent plus, ce qui signifie que vous devrez utiliser des clés avec certaines valeurs. Par exemple, un appel de script utilisant cette fonctionnalité ressemble à ceci :

./monscript -a test1 -b -c test2
Le script doit être capable de détecter quand des options supplémentaires sont utilisées avec les options de ligne de commande :

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Trouvé l'option -a";; -b) param="$2" echo "L'option -b a été trouvée, avec la valeur de paramètre $param" shift ;; -c) echo "L'option -c a été trouvée" ;; --) pause changement ;; *) echo "$1 n'est pas une option";; esac shift done count=1 for param in " [courriel protégé]" do echo "Paramètre #$count : $param" count=$(($count + 1)) done
Appelons ce script comme ceci :

./monscript -a -b test1 -d
Voyons les résultats de son travail.


Gestion des paramètres clés

Dans cet exemple, trois clés sont traitées dans la construction case. Le commutateur -b nécessite un paramètre supplémentaire. Puisque la clé en cours de traitement est dans la variable $1, son paramètre correspondant sera dans $2 (la commande shift est utilisée ici, donc pendant qu'elle est traitée, tout ce qui est passé au script est décalé vers la gauche). Lorsque nous avons traité cela, il ne reste plus qu'à extraire la valeur de la variable $2 et nous aurons le paramètre de la clé souhaitée. Bien sûr, une autre commande shift est nécessaire ici pour que la clé suivante entre dans $1 .

Utilisation des clés standard

Lors de l'écriture de scripts bash, vous pouvez choisir n'importe quelle lettre pour les commutateurs de ligne de commande et définir arbitrairement la réaction du script à ces commutateurs. Cependant, dans le monde Linux, les valeurs de certaines clés sont devenues une sorte de norme qu'il est utile de respecter. Voici une liste de ces clés :
-a Affiche tous les objets.
-c Effectue un comptage.
-d Spécifie un répertoire.
-e Développer l'objet.
-f Spécifiez le fichier à partir duquel lire les données.
-h Affiche l'aide de la commande.
-i Ignorer la casse.
-l Effectue une sortie plein format.
-n Utiliser le mode non interactif (batch).
-o Vous permet de spécifier le fichier vers lequel vous souhaitez rediriger la sortie.
-q Exécute le script en mode silencieux.
-r Traite les dossiers et les fichiers de manière récursive.
-s Exécute le script en mode silencieux.
-v Exécute une sortie détaillée.
-x Exclure l'objet.
-y Répondre "oui" à toutes les questions.

Si vous utilisez Linux, vous connaissez probablement bon nombre de ces clés. En les utilisant dans leur sens conventionnel dans vos scripts, vous aiderez les utilisateurs à interagir avec eux sans avoir à vous soucier de la lecture de la documentation.

Obtenir des données de l'utilisateur

Les commutateurs et les options de la ligne de commande sont un excellent moyen d'obtenir des informations de la part de l'utilisateur du script, mais dans certains cas, une plus grande interactivité est nécessaire.

Parfois, les scripts ont besoin de données que l'utilisateur doit saisir pendant l'exécution du programme. Le shell bash fournit la commande de lecture dans ce but précis.

Cette commande vous permet d'accepter l'entrée soit à partir de l'entrée standard (du clavier), soit à l'aide d'autres descripteurs de fichier. Après avoir récupéré les données, cette commande les place dans une variable :

#!/bin/bash echo -n "Entrez votre nom : " read name echo "Bonjour $name, bienvenue dans mon programme."
Notez que la commande echo, qui imprime l'invite, est invoquée avec l'option -n. Cela se traduit par aucun saut de ligne à la fin de l'invite, ce qui permet à l'utilisateur du script d'entrer des données au même emplacement que l'invite plutôt que sur la ligne suivante.


Gestion des entrées utilisateur

Lors de l'appel de read, vous pouvez spécifier plusieurs variables :

#!/bin/bash read -p "Entrez votre nom : " first last echo "Vos données pour $last, $first…"
C'est ce que le script affichera lors de son exécution.


Plusieurs variables dans la commande de lecture

Si aucune variable n'est spécifiée lors de l'appel de read , les données saisies par l'utilisateur seront placées dans la variable d'environnement spéciale REPLY :

#!/bin/bash read -p "Entrez votre nom : " echo Bonjour $REPLY, bienvenue dans mon programme.


Utilisation de la variable d'environnement REPLY

Si le script doit continuer à s'exécuter, que l'utilisateur saisisse ou non des données, vous pouvez utiliser le commutateur -t lors de l'appel de la commande de lecture. À savoir, le paramètre clé définit le temps d'attente d'entrée en secondes :

#!/bin/bash if read -t 5 -p "Entrez votre nom : " name then echo "Bonjour $nom, bienvenue dans mon script" else echo "Désolé, trop lent !" fi
Si les données ne sont pas entrées dans les 5 secondes, le script exécutera la branche else de l'instruction conditionnelle, en imprimant des excuses.


Délai de saisie des données

Saisie des mots de passe

Parfois, ce que l'utilisateur entre en réponse à la question du script est préférable de ne pas être affiché à l'écran. Par exemple, cela se fait généralement lors de la demande de mots de passe. L'option -s de la commande read empêche l'affichage des entrées au clavier à l'écran. En fait, les données sont sorties, mais la commande de lecture rend la couleur du texte identique à la couleur d'arrière-plan.

#!/bin/bash read -s -p "Entrez votre mot de passe : " pass echo "Votre mot de passe est-il vraiment $pass ?"
Voici comment ce script fonctionnera.


Saisie de données sensibles

Lire les données d'un fichier

La commande de lecture peut, à chaque appel, lire une ligne de texte dans un fichier. Lorsqu'il ne reste plus de lignes non lues dans le fichier, il s'arrête simplement. Si vous avez besoin d'obtenir tout le contenu d'un fichier dans un script, vous pouvez diriger les résultats de l'appel de la commande cat sur le fichier vers la construction while, qui contient la commande read (bien sûr, l'utilisation de la commande cat semble primitive, mais notre objectif est de tout montrer le plus simplement possible, en nous concentrant sur les débutants ; les utilisateurs expérimentés comprendront certainement cela).

Écrivons un script qui utilise l'approche décrite ci-dessus pour lire les fichiers.

#!/bin/bash count=1 chat monfichier | while read line do echo "Ligne $count: $line" count=$(($count + 1)) done echo "Terminé"
Voyons-le en action.


Lire les données d'un fichier

Ici, nous avons passé le contenu du fichier à la boucle while et parcouru toutes les lignes de ce fichier, en affichant le nombre et le contenu de chacune d'entre elles.

Résultats

Aujourd'hui, nous avons analysé le travail avec les commutateurs et les paramètres de ligne de commande. Sans ces outils, le champ d'utilisation des scripts est extrêmement restreint. Même si le scénario est écrit, comme on dit, "pour moi". Là, nous avons envisagé des approches pour recevoir des données de l'utilisateur lors de l'exécution du programme - cela rend les scripts interactifs.

La prochaine fois, nous parlerons des opérations d'entrée et de sortie.

Chers lecteurs! Merci de partager votre expérience dans les commentaires sur les parties précédentes de cette série de documents. Si vous avez quelque chose à dire sur la gestion de tout ce qui peut être transmis à un script au démarrage ou pendant son exécution, nous sommes sûrs que beaucoup seront intéressés à en savoir plus.

J'ai créé un script avec la magie getopt standard, vous pouvez donc appeler le script avec

Batman-connect -c ffki

Comment ajouter un paramètre pour appeler ce script avec un seul paramètre sans tiret ?

batman connecter ffki

il interprétera donc cette option unique comme le deuxième argument de -c ?

Selon cette réponse, j'ai essayé:

si[ [courriel protégé]= "ffki" ]; puis définissez -- "-c [courriel protégé]" Fi

Mais cela entraîne une erreur, je pense, car cette ligne de mon script va le changer :

# Exécute getopt sur les arguments passés à ce programme, identifiés par le caractère spécial [courriel protégé] PARSED_OPTIONS=$(getopt -n "$0" -o hsrvVi:c: --long "help,start,restart,stop,verbose,vv,version,interface:,community:" -- " [courriel protégé]")

Je n'aime pas avoir à réinstaller tout mon script, alors existe-t-il une simple ligne pour définir le premier argument sur '-c' et le second sur 'ffki'?

4 Les solutions collectent le formulaire Web pour "Modifier les arguments bash si un seul argument est donné"

Vous pouvez faire quelque chose comme

Si [ $# = 1 ] ; then # faites ce que vous feriez quand il n'y a qu'un seul argument else # faites les bits getopt fi # faites ce que vous feriez dans les deux cas

Si -c est le seul commutateur que vous souhaitez prendre en charge, vous n'avez pas besoin de getopt et à la place, vous pouvez faire quelque chose comme ceci :

#!/bin/bash usage() ( echo "Utilisation : $0 [ -c ] arg" >&2 exit 1 ) if [ $# = 2 ]; alors si [ $1 = "-c" ]; then shift c_switch_value="$1" else use fi elif [ $# = 1 ]; then c_switch_value="$1" sinon utiliser fi

Que ce soit plus lisible est discutable, cependant.

Si [ $# = 1 ] ; then # S'il n'y a qu'un seul argument, remplace le processus en cours par la nouvelle invocation du script # la seule option sera utilisée comme -c option exec "$0" -c " [courriel protégé]" Fi

Cela ne répond pas à la question d'origine, mais c'est une solution de contournement qui fonctionne dans mon cas particulier.

La commande dans la clause if se développe en [suivi d'une liste de développements de substitution de mots qui composent les paramètres positionnels suivants avec les mots =ffki]. De manière générale, $VAR ne signifie pas "valeur VAR" lorsqu'il est en dehors des guillemets doubles, cela signifie "diviser la valeur VAR en mots séparés et les interpréter comme des globs". Voir Pourquoi mon script shell s'étouffe-t-il avec des espaces ou d'autres caractères spéciaux ?

Outre, " [courriel protégé]" est un cas particulier : il se développe en une liste de paramètres positionnels (pas d'extension supplémentaire), et non en un seul mot (malgré les guillemets). Vous pouvez utiliser "$*" , qui se développe en un seul mot composé de paramètres positionnels séparés par un espace (plus précisément, le premier caractère de la valeur IFS) Donc pour vérifier s'il y a un seul paramètre positionnel dont la valeur est ffki , vous pouvez utiliser

Si [ "$*" = "ffki" ] ; alors

Si [ $# -eq 1 ] && [ "$1" = "ffki" ]; alors

Pour modifier les paramètres positionnels, vous étiez proche : utilisez la commande intégrée set et transmettez le nouvel ensemble de paramètres positionnels en tant qu'arguments séparés. S'il y a un risque que le premier paramètre commence par un - , utilisez set -- ... pour qu'il ne soit pas interprété comme une option.

Si [ "$*" = "ffki" ] ; puis définissez -- -c "ffki" fi

Vous avez aimé l'article ? Partager avec des amis: