Retour au cours

getopts

Objectifs

  • Parser les options courtes de ligne de commande (ex: -f, -v) de manière robuste et standard.
  • Gérer les options qui attendent une valeur (ex: -o fichier.txt).
  • Détecter les options invalides et afficher un message d’aide.
  • Traiter les arguments restants après que les options ont été parsées.

Explications détaillées

Notions clés

Quand un script devient plus complexe, il a souvent besoin d’options pour modifier son comportement. Parser ces options manuellement avec des if et shift est fastidieux et source d’erreurs. getopts est la commande intégrée à Bash conçue pour cette tâche.

La boucle while getopts

Le cœur du parsing se fait dans une boucle while qui exécute getopts.

while getopts ":a:b:c" opt; do
  case "$opt" in
    # ...
  esac
done
  • getopts ":a:b:c" opt : C’est la commande magique.
    • La première chaîne (":a:b:c") définit les options valides.
      • Une lettre seule (c) définit une option “flag” comme -c.
      • Une lettre suivie de deux-points (a:) définit une option qui attend un argument, comme -a valeur.
      • Le tout premier : (: au début) active le mode silencieux, qui permet de gérer les erreurs soi-même. C’est une bonne pratique.
    • opt est le nom de la variable qui contiendra l’option trouvée à chaque tour de boucle (sans le -).

La structure case

À l’intérieur de la boucle, on utilise une structure case pour agir en fonction de l’option trouvée.

case "$opt" in
  a)
    valeur_a="$OPTARG"
    ;;
  b)
    valeur_b="$OPTARG"
    ;;
  c)
    option_c_active=true
    ;;
  \?)
    echo "Option invalide: -$OPTARG" >&2
    exit 1
    ;;
  :)
    echo "L'option -$OPTARG attend un argument." >&2
    exit 1
    ;;
esac
  • $OPTARG : C’est une variable spéciale qui contient la valeur passée à une option (pour a: et b:).
  • \? : Ce cas est déclenché si une option inconnue est utilisée. L’option fautive est dans $OPTARG.
  • : : Ce cas est déclenché si une option attend un argument mais ne l’a pas reçu. L’option est dans $OPTARG.

shift pour nettoyer

Après la boucle while, $@ contient encore les options. La commande shift $((OPTIND - 1)) permet de supprimer tous les arguments qui ont été parsés par getopts, ne laissant que les arguments positionnels restants.

  • $OPTIND : Une autre variable spéciale qui contient l’index du prochain argument à traiter.

Syntaxe / Usages

# Squelette complet d'un script avec getopts
#!/bin/bash
set -euo pipefail

# Fonction pour afficher l'aide
usage() {
  echo "Usage: $0 [-v] [-o <fichier>] <argument_final>"
  exit 1
}

# Initialisation des variables
VERBOSE=false
OUTPUT_FILE=""

while getopts ":vo:" opt; do
  case "$opt" in
    v)
      VERBOSE=true
      ;;
    o)
      OUTPUT_FILE="$OPTARG"
      ;;
    \? | :)
      usage
      ;;
  esac
done

# On supprime les options pour ne garder que les arguments positionnels
shift $((OPTIND - 1))

# On vérifie qu'il reste bien un argument
if [[ $# -ne 1 ]]; then
  usage
fi

ARGUMENT_FINAL="$1"

# Logique du script...
if [[ "$VERBOSE" == true ]]; then
  echo "Mode verbeux activé."
fi

if [[ -n "$OUTPUT_FILE" ]]; then
  echo "La sortie sera écrite dans : $OUTPUT_FILE"
fi

echo "Argument final traité : $ARGUMENT_FINAL"

Exemples d’exécution

$ ./mon_script.sh -v -o rapport.txt mon_fichier
Mode verbeux activé.
La sortie sera écrite dans : rapport.txt
Argument final traité : mon_fichier

$ ./mon_script.sh -x # Option invalide
Usage: ./mon_script.sh [-v] [-o <fichier>] <argument_final>

Bonnes pratiques

  • Utilisez getopts pour tout script ayant des options. C’est la méthode standard, portable et robuste.
  • Commencez toujours la chaîne d’options par un : pour activer le mode silencieux et gérer vous-même les erreurs.
  • Écrivez une fonction usage() qui affiche l’aide et quitte le script. Appelez-la en cas d’erreur d’arguments.
  • Initialisez vos variables avant la boucle pour avoir des valeurs par défaut saines.

Pièges courants

  • Oublier shift $((OPTIND - 1)) : Si vous l’oubliez, les options (-v, -o, etc.) resteront dans $@, ce qui perturbera le traitement des arguments positionnels restants.
  • Parser les options longues (--verbose) : getopts ne gère nativement que les options courtes (-v). Pour les options longues, il faut utiliser des astuces plus complexes ou un autre outil comme getopt (avec un ‘t’). Pour débuter, tenez-vous-en aux options courtes.

Exercices

  1. Script de salutation amélioré :

    • Créez un script saluer.sh qui accepte les options suivantes :
      • -n <nom> : Le nom de la personne à saluer (obligatoire).
      • -l <langue> : fr ou en (optionnel, fr par défaut).
    • Le script doit afficher “Bonjour, [nom]” ou “Hello, [nom]” selon la langue.
    • S’il manque l’option -n, le script doit afficher une aide.
  2. Créateur de fichiers :

    • Écrivez un script creer.sh qui prend un nom de fichier en argument positionnel.
    • Ajoutez une option -s <taille> pour créer un fichier d’une certaine taille en kilooctets (utiliser truncate -s ${taille}K "$fichier").
    • Ajoutez une option -v (verbose) qui affiche des détails sur l’opération.
    • Exemple : ./creer.sh -v -s 10 mon_fichier.dat
  3. Gestion d’erreurs :

    • Modifiez l’un des scripts précédents pour qu’il affiche un message d’erreur clair et l’aide si une option invalide est utilisée (ex: -x).