Retour au cours

parametres positions

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. $1 est le premier, $2 le 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éciale IFS (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 $2 devient le nouveau $1.
  • L’ancien $3 devient le nouveau $2.
  • L’ancien $1 est 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, utilisez shift ou 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 à $1 alors que $# est 0, la variable sera vide. Si vous utilisez set -u, votre script s’arrêtera avec une erreur, ce qui est une bonne pratique.
  • Confondre $? (code de sortie) et $# (nombre d’arguments).

Exercices

  1. Script d’information :

    • Créez un script qui affiche :
      1. Le nom du script.
      2. Le nombre d’arguments reçus.
      3. Le dernier argument reçu (sans utiliser shift). Indice : eval peut être une solution, mais attention, c’est généralement dangereux. Une solution avec les tableaux est plus sûre.
  2. Script somme :

    • Écrivez un script qui prend un nombre indéfini d’entiers en arguments et affiche leur somme.
    • Utilisez une boucle for sur "$@" et l’arithmétique Bash.
    • Exemple : ./somme.sh 10 20 5 doit afficher 35.
  3. Parser avec shift :

    • Écrivez une boucle while qui utilise shift pour parcourir tous les arguments et les afficher un par un.
    • Le script doit afficher “Argument traité : [arg]” pour chaque argument.