C'est une vieille citation, mais je pense que ce principe de l'inventeur de Perl, Larry Wall, est toujours valable :
"Le programmeur paresseux réutilisera tout ce qu'il peut pour faire son travail. Cette vertu conduit à la réutilisation du code en encourageant le code à n'être écrit qu'une seule fois."
— Larry Wall, "Les trois vertus d'un programmeur"
Disons que vous en avez assez de taper la même séquence de commandes et que vous créez enfin un joli script shell pour exécuter des choses avec moins de frappes. Mais parfois, vous voulez l'exécuter avec des arguments différents, et vous définitivement ne voulez pas dupliquer votre excellent script. Vous avez besoin d'un moyen de fournir et d'utiliser des arguments à partir de la ligne de commande. Cet article couvre exactement cela.
Traiter les entrées de script
Les scripts shell ont accès à certaines variables "magiques" de l'environnement :
$0
- Le nom du script$1
- Le premier argument envoyé au script$2
- Le deuxième argument envoyé au script$3
- Le troisième argument... et ainsi de suite$#
- Le nombre d'arguments fournis$@
- Une liste de tous les arguments fournis
#!/bin/bash
if [ $# -eq 0 ];
then
echo "$0: Missing arguments"
exit 1
elif [ $# -gt 2 ];
then
echo "$0: Too many arguments: $@"
exit 1
else
echo "We got some argument(s)"
echo "==========================="
echo "Number of arguments.: $#"
echo "List of arguments...: $@"
echo "Arg #1..............: $1"
echo "Arg #2..............: $2"
echo "==========================="
fi
echo "And then we do something with $1 $2"
Voici quelques exemples d'exécution avec différentes combinaisons d'arguments :
$ ./ex01.sh
./ex01.sh: Missing arguments
$ ./ex01.sh aa
We got some argument(s)
===========================
Number of arguments.: 1
List of arguments...: aa
Arg #1..............: aa
Arg #2..............:
===========================
And then we do something with aa
$ ./ex01.sh aa bb
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb
Arg #1..............: aa
Arg #2..............: bb
===========================
And then we do something with aa bb
$ ./ex01.sh aa bb cc
./ex01.sh: Too many arguments: aa bb cc
C'est bien si vous avez un ou deux arguments. Cependant, notez que le séparateur par défaut entre les arguments est le caractère Espace. Et parce que Space est le séparateur par défaut pour les arguments, des choses intéressantes peuvent se produire. Voici par exemple ce qui se passe si vous utilisez des guillemets avec plus de deux arguments :
$ ./ex01.sh aa "bb cc xx yy zz"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb cc xx yy zz
Arg #1..............: aa
Arg #2..............: bb cc xx yy zz
===========================
And then we do something with aa bb cc xx yy zz
Notez que le script interprète bb cc xx yy zz
comme un argument car les valeurs sont entre guillemets doubles, ce qui est également très bien si c'est ce que vous voulez.
[ Gardez vos commandes Linux à portée de main. Téléchargez l'aide-mémoire des commandes Linux avancées. ]
Une autre chose intéressante est lorsque votre script obtient des arguments de variables . Si la variable contient des espaces, vous devez décider si vous voulez que valeur à traiter comme un seul argument ou toutes les parties à traiter comme des arguments différents :
$ export AUTHOR="John Lennon"
$ export SONG="Imagine"
$ ./ex01.sh $AUTHOR $SONG
./ex01.sh: Too many arguments: John Lennon Imagine
$ ./ex01.sh "$AUTHOR" "$SONG"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: John Lennon Imagine
Arg #1..............: John Lennon
Arg #2..............: Imagine
===========================
And then we do something with John Lennon Imagine
Lorsque vous envoyez les arguments en tant que variables sans guillemets, le script les interprète tous comme des mots séparés et "voit" trois arguments :John , Lennon , et Imaginez .
Utiliser des guillemets autour les variables font que le script reçoit chaque variable comme un argument, ce qui est plus logique dans ce cas.
Traitez beaucoup plus d'arguments
Comme vous l'avez vu, la variable magique $@
contient la liste de tous les arguments reçus par le script. Vous pouvez utiliser une boucle pour traiter tous les arguments :
#!/bin/bash
echo "We received $# argument(s)"
for i in "$@"
do
echo "Arg...: $i"
done
Ce qui vous donne ceci :
$ ./ex02.sh a b c e "stuff with spaces"
We received 5 argument(s)
Arg...: a
Arg...: b
Arg...: c
Arg...: e
Arg...: stuff with spaces
Soyez intelligent en étant paresseux
Les choses importantes lorsque vous traitez des arguments dans vos scripts shell sont d'avoir une compréhension claire de :
- Quelle forme le contenu d'un argument peut-il prendre ?
- S'il est fourni en tant que variable, qu'est-ce que "l'expéditeur" a mis dans cette variable pour vous ?
- Si elle est fournie par l'utilisateur, comment pouvez-vous vous assurer que l'utilisateur ne "casse" pas votre logique ?
- Quels arguments sont acceptables ou obligatoires pour votre scénario?
- Que voulez-vous faire si les arguments ne sont pas valides ? Le script peut générer une erreur ou peut-être utiliser des valeurs par défaut.
J'espère que cela vous aidera à continuer à être paresseux de la bonne manière... en améliorant ou en réutilisant certains de vos scripts.