Objectifs
- Accéder aux arguments passés à un script ou à une fonction en utilisant les variables positionnelles.
- Connaître le nombre d’arguments reçus.
- Comprendre la différence fondamentale entre
"$*"et"$@". - Itérer de manière sûre sur la liste de tous les arguments.
- Traiter les arguments séquentiellement avec la commande
shift.
Explications détaillées
Notions clés
Lorsque vous lancez un script avec des arguments (./mon_script.sh arg1 "argument 2"), Bash met ces arguments à votre disposition via des variables spéciales, appelées “paramètres positionnels”.
Les variables de base
$0: Contient le nom du script lui-même.$1,$2,$3, …$9: Contiennent les arguments individuels.$1est le premier,$2le deuxième, etc.$#: Contient le nombre total d’arguments passés au script.
$* vs $@ : Tous les arguments
Ces deux variables spéciales représentent “tous les arguments”, mais leur comportement diffère énormément lorsqu’elles sont utilisées avec des guillemets doubles.
"$*": Se développe en une seule chaîne de caractères contenant tous les arguments, séparés par le premier caractère de la variable spécialeIFS(par défaut, un espace)."$@": Se développe en une liste de chaînes de caractères distinctes. Chaque argument original reste un élément séparé, même s’il contient des espaces.
Dans 99% des cas, "$@" est ce que vous voulez utiliser.
shift : Décaler les arguments
La commande shift décale tous les paramètres positionnels vers la gauche.
- L’ancien
$2devient le nouveau$1. - L’ancien
$3devient le nouveau$2. - L’ancien
$1est perdu. $#est décrémenté.
C’est très utile pour traiter les arguments un par un dans une boucle while.
Syntaxe / Usages
# Accéder aux premiers arguments
premier_arg="$1"
deuxieme_arg="$2"
# Vérifier le nombre d'arguments
if [[ "$#" -lt 1 ]]; then
echo "Usage: $0 <argument1> [argument2...]"
exit 1
fi
# Itérer sur tous les arguments de manière sûre
for arg in "$@"; do
echo "Argument traité : '$arg'"
done
# Passer tous les arguments à une autre commande
autre_commande "$@"
# Traiter les arguments avec shift
while [[ "$#" -gt 0 ]]; do
echo "Traitement de : $1"
shift
done
Exemples
# Créez un script 'test_args.sh' avec le contenu suivant :
#!/bin/bash
set -euo pipefail
echo "Le script s'appelle : $0"
echo "Nombre d'arguments : $#"
echo "Premier argument : $1"
echo "Deuxième argument : $2"
echo "--- Boucle sur \"\$@\" ---"
for i in "$@"; do
echo " -> '$i'"
done
echo "--- Boucle sur \"\$*\" ---"
for i in "$*"; do
echo " -> '$i'"
done
Exécution et résultat :
$ ./test_args.sh "un" "deux trois"
Le script s'appelle : ./test_args.sh
Nombre d'arguments : 2
Premier argument : un
Deuxième argument : deux trois
--- Boucle sur "$@" ---
-> 'un'
-> 'deux trois'
--- Boucle sur "$*" ---
-> 'un deux trois'
Cet exemple montre clairement que "$@" préserve les arguments comme des entités distinctes, tandis que "$*" les fusionne en une seule chaîne.
Bonnes pratiques
- Utilisez toujours
"$@"entre guillemets doubles pour itérer sur les arguments ou les passer à une autre commande. C’est la méthode la plus sûre pour gérer correctement les arguments contenant des espaces. - Vérifiez
$#au début de vos scripts pour vous assurer que l’utilisateur a fourni le bon nombre d’arguments. - Si vous devez accéder à des arguments au-delà de
$9, utilisezshiftou la syntaxe d’expansion de tableau${@:10:1}.
Pièges courants
- Utiliser
$*ou$@sans guillemets :for i in $@cassera les arguments contenant des espaces. C’est une source de bugs très fréquente. - Accéder à un argument qui n’existe pas : Si vous accédez à
$1alors que$#est0, la variable sera vide. Si vous utilisezset -u, votre script s’arrêtera avec une erreur, ce qui est une bonne pratique. - Confondre
$?(code de sortie) et$#(nombre d’arguments).
Exercices
-
Script d’information :
- Créez un script qui affiche :
- Le nom du script.
- Le nombre d’arguments reçus.
- Le dernier argument reçu (sans utiliser
shift). Indice :evalpeut être une solution, mais attention, c’est généralement dangereux. Une solution avec les tableaux est plus sûre.
- Créez un script qui affiche :
-
Script
somme:- Écrivez un script qui prend un nombre indéfini d’entiers en arguments et affiche leur somme.
- Utilisez une boucle
forsur"$@"et l’arithmétique Bash. - Exemple :
./somme.sh 10 20 5doit afficher35.
-
Parser avec
shift:- Écrivez une boucle
whilequi utiliseshiftpour parcourir tous les arguments et les afficher un par un. - Le script doit afficher “Argument traité : [arg]” pour chaque argument.
- Écrivez une boucle