Maîtriser l'analyse des arguments Bash pour des scripts puissants
Les arguments de ligne de commande sont l'épine dorsale des scripts Bash flexibles et réutilisables. Sans une analyse efficace des arguments, un script reste un outil rigide, capable uniquement d'actions prédéfinies. Maîtriser l'analyse des arguments vous permet de transformer de simples tâches d'automatisation en outils de ligne de commande professionnels, robustes et conviviaux.
Ce guide explore les techniques essentielles pour gérer les arguments positionnels, les options courtes (flags) et les options longues en Bash, en se concentrant sur l'utilitaire standard getopts et les boucles d'analyse personnalisées, garantissant que vos scripts peuvent gérer des configurations complexes avec élégance.
1. Les bases : Les arguments positionnels
Avant d'aborder les flags et les options nommées, il est crucial de comprendre comment Bash gère les arguments simples et séquentiels.
| Variable | Description | Exemple (si le script est appelé ./script.sh foo bar) |
|---|---|---|
$0 |
Le nom du script lui-même | ./script.sh |
$1, $2, ... |
Le premier, deuxième, etc., argument positionnel | foo, bar |
$# |
Le nombre d'arguments positionnels | 2 |
$@ |
Tous les arguments positionnels, traités comme des chaînes de caractères distinctes | foo bar |
$* |
Tous les arguments positionnels, traités comme une seule chaîne de caractères | foo bar |
Exemple : Vérification positionnelle simple
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <source_file> <destination_dir>"
exit 1
fi
SOURCE="$1"
DESTINATION="$2"
echo "Copying $SOURCE to $DESTINATION..."
# cp "$SOURCE" "$DESTINATION"
2. Analyse standard avec getopts (options courtes)
Pour les scripts professionnels qui nécessitent des options comme -v (verbeux) ou -f <fichier>, l'utilitaire getopts intégré est la méthode canonique et la plus fiable en Bash pur. Il est conçu spécifiquement pour les options courtes (à un seul caractère).
Comment getopts fonctionne
getopts lit les options séquentiellement, en définissant la variable désignée (généralement OPT) à l'option trouvée, et en plaçant la valeur de tout argument (si nécessaire) dans la variable OPTARG.
- Chaîne d'options (OPTSTRING) : Définit les options valides. Si une option nécessite un argument (par exemple,
-f nom_fichier), faites suivre le caractère d'un deux-points (:). Exemple :vho:autorise-v,-het-oqui nécessite une valeur. OPTIND: Un index interne de Bash qui suit le prochain argument à traiter. Il doit être initialisé à 1 (ce qui est la valeur par défaut, mais parfois réinitialisé dans des scripts complexes).
Modèle getopts pratique
Ce modèle gère trois options : -v (flag), -h (flag) et -f (option nécessitant une valeur).
#!/bin/bash
# --- Valeurs par défaut ---
VERBOSE=0
FILENAME="default.txt"
# --- Fonction d'utilisation ---
usage() {
echo "Utilisation : $0 [-v] [-h] [-f <fichier>] <entrée>"
exit 1
}
# --- Boucle d'analyse des arguments ---
while getopts "v:hf:" OPT; do
case "$OPT" in
v)
VERBOSE=1
echo "Mode verbeux activé."
;;
h)
usage
;;
f)
# OPTARG contient l'argument fourni à -f
FILENAME="$OPTARG"
echo "Nom du fichier de sortie défini sur : $FILENAME"
;;
\?)
# Gère les options non reconnues ou les arguments manquants
echo "Erreur : Option invalide -$OPTARG" >&2
usage
;;
:)
# Gère les arguments manquants pour les options qui en nécessitent un (par exemple, -f sans nom de fichier)
echo "Erreur : L'option -$OPTARG nécessite un argument." >&2
usage
;;
esac
done
# --- Décalage des arguments positionnels ---
# Une fois que getopts a terminé, OPTIND contient l'index du premier argument non-option.
# Nous utilisons shift pour ignorer toutes les options analysées, ne laissant que les arguments positionnels ($1, $2, etc.).
shift $((OPTIND - 1))
# Vérifie si l'argument positionnel requis (INPUT) est présent
INPUT_DATA="$1"
if [ -z "$INPUT_DATA" ]; then
echo "Erreur : Données d'entrée requises."
usage
fi
echo "---"
echo "Traitement de l'entrée : $INPUT_DATA"
echo "Statut verbeux : $VERBOSE"
Astuce : Utilisez toujours
shift $((OPTIND - 1))immédiatement après la bouclewhile getoptspour séparer proprement les options des arguments positionnels restants.
3. Gérer les options longues (--option)
L'utilitaire getopts intégré de Bash pur ne prend en charge que les options courtes. Pour gérer les options longues modernes (par exemple, --verbose, --output-file=data.log), vous devez implémenter une boucle d'analyse personnalisée utilisant while et case avec la commande shift.
Cette méthode nécessite une gestion plus explicite des arguments.
Analyseur d'options longues personnalisé
#!/bin/bash
# --- Valeurs par défaut ---
VERBOSE=0
OUTPUT_FILE=""
# Fonction personnalisée pour afficher l'utilisation (omise pour des raisons de concision)
# usage() { ... }
while [ "$#" -gt 0 ]; do
case "$1" in
--verbose)
VERBOSE=1
shift
;;
--output-file)
# Nécessite deux shifts : un pour le flag, un pour la valeur
if [ -z "$2" ]; then
echo "Erreur : --output-file nécessite une valeur."
exit 1
fi
OUTPUT_FILE="$2"
shift 2
;;
--help)
usage
;;
-*)
echo "Erreur : Option inconnue $1" >&2
exit 1
;;
*)
# Premier argument positionnel trouvé, arrêt de l'analyse des options
break
;;
esac
done
# Les arguments restants sont maintenant disponibles en tant que $1, $2, etc.
# ... La logique du script continue ...
if [ "$OUTPUT_FILE" ]; then
echo "Données redirigées vers $OUTPUT_FILE"
fi
Avancé : Gérer les options longues clé-valeur (--clé=valeur)
Si vous préférez le style UNIX standard où les arguments sont passés à l'aide d'un signe égal, vous devez utiliser la substitution de paramètres pour diviser l'argument.
while [ "$#" -gt 0 ]; do
case "$1" in
--limit=*)
LIMIT_VAL="${1#*=}" # Supprimer tout ce qui précède et inclut '='
echo "Limite définie à : $LIMIT_VAL"
shift
;;
# ... autres options ...
esac
done
4. Bonnes pratiques pour un scripting robuste
A. Combiner les options courtes et longues
Pour une flexibilité maximale, les scripteurs expérimentés combinent souvent la fiabilité de getopts pour les options courtes avec la boucle while/case personnalisée pour les options longues. La boucle d'options longues s'exécute en premier, consommant les flags longs, puis les arguments restants (y compris les options courtes) sont traités par getopts.
Cependant, un modèle plus propre et courant est de traiter tous les arguments dans une seule boucle personnalisée robuste qui recherche à la fois -o et --option, en décalant les arguments en conséquence.
B. Gestion des erreurs et utilisation
Fournissez toujours une fonction usage claire qui explique les arguments et options requis du script. Cette fonction doit être appelée lorsque :
- L'utilisateur demande de l'aide (par exemple,
-hou--help). - Un argument requis est manquant.
- Une option invalide ou inconnue est fournie.
Assurez-vous que le script se termine avec un statut non nul en cas d'erreur (exit 1) et affiche les messages d'erreur sur la sortie d'erreur standard (>&2).
C. Valeurs par défaut
Initialisez toutes les variables de configuration au début du script avec des valeurs par défaut pertinentes. Cela rend votre script prévisible même si aucun argument facultatif n'est passé.
# Toujours initialiser les variables avant l'analyse
LOG_LEVEL="info"
FORCE=0
Conclusion
Maîtriser l'analyse des arguments transforme un simple script Bash en un utilitaire de ligne de commande polyvalent. Bien que les arguments positionnels ($1, $2) suffisent pour les tâches les plus simples, l'utilisation de getopts pour les options courtes garantit la conformité aux normes POSIX et une analyse robuste. Pour les options longues, une boucle while dédiée avec shift offre la flexibilité requise pour les outils CLI modernes. En intégrant une analyse robuste, des valeurs par défaut pertinentes et des messages d'utilisation clairs, vos scripts d'automatisation deviennent considérablement plus puissants et gérables.