Introduction
Bash, le Bourne-Again SHell, est une interface de ligne de commande et un langage de scripting largement utilisés dans les systèmes d'exploitation Linux et Unix-like. L'une des fonctionnalités puissantes de Bash est sa capacité à gérer les arguments de ligne de commande, permettant aux utilisateurs de passer des informations supplémentaires à des scripts ou des programmes. L'utilitaire "bash getopt" simplifie le processus d'analyse des arguments de ligne de commande, facilitant la création d'interfaces de ligne de commande conviviales pour vos scripts Bash.
Dans ce laboratoire, vous allez apprendre à utiliser getopt pour gérer les options de ligne de commande dans vos scripts Bash, les rendant plus flexibles et conviviaux. À la fin de ce laboratoire, vous serez capable de créer des scripts qui acceptent à la fois les options courtes (comme -f) et les options longues (comme --file), d'analyser les arguments et de mettre en œuvre une gestion d'erreurs appropriée.
Comprendre les bases des arguments de ligne de commande
Avant d'approfondir getopt, comprenons comment les scripts Bash traitent normalement les arguments de ligne de commande. En Bash, lorsque vous passez des arguments à un script, ils sont accessibles grâce à des variables spéciales :
$0: Le nom du script lui-même$1,$2,$3, etc. : Les premiers, seconds, troisièmes, etc. arguments positionnels$#: Le nombre d'arguments passés au script$@: Tous les arguments passés au script
Créeons un script simple pour démontrer ce traitement de base des arguments de ligne de commande.
Création de votre premier script
Ouvrez le terminal dans votre environnement LabEx.
Accédez au répertoire du projet :
cd ~/projetCréez un nouveau fichier appelé
basic_args.shà l'aide de l'éditeur :touch basic_args.shOuvrez le fichier dans l'éditeur et ajoutez le contenu suivant :
#!/bin/bash echo "Nom du script : $0" echo "Premier argument : $1" echo "Second argument : $2" echo "Troisième argument : $3" echo "Nombre total d'arguments : $#" echo "Tous les arguments : $@"Rendez le script exécutable :
chmod +x basic_args.shExécutez le script avec quelques arguments :
./basic_args.sh pomme banane cerise
Vous devriez voir une sortie similaire à celle-ci :
Nom du script :./basic_args.sh
Premier argument : pomme
Second argument : banane
Troisième argument : cerise
Nombre total d'arguments : 3
Tous les arguments : pomme banane cerise
Limites du traitement d'arguments de base
Si cette approche de base fonctionne pour les scripts simples, elle présente plusieurs limites :
- Pas de distinction entre les options (comme
-fou--file) et les arguments normaux - Pas de moyen de gérer les options qui ont leurs propres arguments
- Pas de manière standard de valider l'entrée de l'utilisateur
- Difficile d'implémenter à la fois les options de forme courte et longue
Par exemple, si vous vouliez un script qui pourrait être appelé comme ceci :
./myscript.sh -f fichier.txt -o sortie.txt --verbose
Vous devriez analyser manuellement chaque argument pour déterminer s'il s'agit d'une option ou non, et gérer les paramètres associés. Cela devient rapidement complexe et propice aux erreurs.
C'est là que la commande getopt intervient. Elle fournit une manière standardisée de gérer les options et les arguments de ligne de commande dans les scripts Bash.
Présentation de getopt
La commande getopt aide à analyser les options de ligne de commande et leurs arguments de manière plus structurée. Elle prend en charge à la fois les options courtes (options à une lettre avec un seul tiret, comme -f) et les options longues (options à plusieurs lettres avec deux tirets, comme --file).
Syntaxe de base de getopt
La syntaxe de base pour utiliser getopt est la suivante :
getopt [options] -- "$@"
Où [options] définit les options de ligne de commande que votre script acceptera, et "$@" passe tous les arguments donnés à votre script.
Les options communes de getopt sont les suivantes :
-o "options": Spécifie les options courtes que votre script accepte (par exemple,-o "hvo:")--long "options": Spécifie les options longues que votre script accepte (par exemple,--long "help,verbose,output:")-n "name": Le nom à utiliser dans les messages d'erreur (généralement le nom de votre script)
Format de la chaîne d'options
Dans les chaînes d'options :
- Une lettre seule signifie que l'option ne prend pas d'argument (par exemple,
hpour-h) - Une lettre suivie d'un deux-points signifie que l'option nécessite un argument (par exemple,
o:pour-o valeur) - Une lettre suivie de deux deux-points signifie que l'option a un argument facultatif (par exemple,
v::pour-vou-vvaleur)
Essayons un exemple simple
Créeons un script qui utilise getopt pour analyser quelques options de base :
Créez un nouveau fichier appelé
simple_getopt.sh:touch simple_getopt.shOuvrez le fichier dans l'éditeur et ajoutez le contenu suivant :
#!/bin/bash ## Analyse les options de ligne de commande OPTS=$(getopt -o hv --long help,verbose -n'simple_getopt.sh' -- "$@") if [ $? -ne 0 ]; then echo "Échec de l'analyse des options" >&2 exit 1 fi ## Remet les paramètres positionnels aux options analysées eval set -- "$OPTS" ## Initialise les variables HELP=false VERBOSE=false ## Traite les options while true; do case "$1" in -h | --help) HELP=true shift ;; -v | --verbose) VERBOSE=true shift ;; --) shift break ;; *) echo "Erreur interne!" exit 1 ;; esac done ## Affiche les résultats if [ "$HELP" = true ]; then echo "Aide activée" fi if [ "$VERBOSE" = true ]; then echo "Mode verbeux activé" fi echo "Arguments restants : $@"Rendez le script exécutable :
chmod +x simple_getopt.shExécutez le script avec différentes options :
./simple_getopt.sh -hSortie :
Aide activée Arguments restants :./simple_getopt.sh --verbose arguments supplémentairesSortie :
Mode verbeux activé Arguments restants : arguments supplémentaires./simple_getopt.sh -h -v plus d'argumentsSortie :
Aide activée Mode verbeux activé Arguments restants : plus d'arguments
Comment getopt fonctionne
Analysons comment le script fonctionne :
getopt -o hv --long help,verbose -n'simple_getopt.sh' -- "$@"- Cela analyse les arguments de ligne de commande selon les options spécifiées
-o hvdéfinit les options courtes-het-v--long help,verbosedéfinit les options longues--helpet--verbose-n'simple_getopt.sh'spécifie le nom du script pour les messages d'erreur"$@"passe tous les arguments du script à getopt
eval set -- "$OPTS"- Cela remet les paramètres positionnels aux options analysées
La boucle
whiletraite chaque option :- Chaque cas correspond à une option et définit la variable correspondante
shiftpasse à l'option suivante--marque la fin des options ; tout ce qui suit est un argument non optionnelbreaksort de la boucle après avoir traité toutes les options
Voici les bases de l'utilisation de getopt dans les scripts Bash. Dans l'étape suivante, nous allons construire sur cela pour gérer les options qui nécessitent des arguments.
Gérer les options avec des arguments
De nombreux outils de ligne de commande nécessitent des options qui prennent des arguments. Par exemple, -f nom_du_fichier ou --file nom_du_fichier. Dans cette étape, nous allons apprendre à gérer les options avec des arguments à l'aide de getopt.
Syntaxe pour les options avec des arguments
Pour spécifier qu'une option nécessite un argument :
- Pour les options courtes : Ajoutez un deux-points après l'option dans la chaîne
-o(par exemple,"f:") - Pour les options longues : Ajoutez un deux-points après l'option dans la chaîne
--long(par exemple,"file:")
Création d'un script avec des arguments d'option
Créeons un script qui traite des fichiers et des répertoires en utilisant des options avec des arguments :
Créez un nouveau fichier appelé
file_processor.sh:touch file_processor.shOuvrez le fichier dans l'éditeur et ajoutez le contenu suivant :
#!/bin/bash ## Analyse les options de ligne de commande OPTS=$(getopt -o f:d:h --long file:,directory:,help -n 'file_processor.sh' -- "$@") if [ $? -ne 0 ]; then echo "Échec de l'analyse des options" >&2 exit 1 fi ## Remet les paramètres positionnels aux options analysées eval set -- "$OPTS" ## Initialise les variables FICHIER="" DOSSIER="" AIDE=false ## Traite les options while true; do case "$1" in -f | --file) FICHIER="$2" shift 2 ;; -d | --directory) DOSSIER="$2" shift 2 ;; -h | --help) AIDE=true shift ;; --) shift break ;; *) echo "Erreur interne!" exit 1 ;; esac done ## Affiche les résultats if [ "$AIDE" = true ]; then echo "Usage : $0 [-f|--file FICHIER] [-d|--directory DOSSIER] [-h|--help]" echo "" echo "Options :" echo " -f, --file FICHIER Spécifie un fichier à traiter" echo " -d, --directory DOSSIER Spécifie un répertoire à traiter" echo " -h, --help Affiche ce message d'aide" exit 0 fi if [ -n "$FICHIER" ]; then if [ -f "$FICHIER" ]; then echo "Traitement du fichier : $FICHIER" echo "Taille du fichier : $(wc -c < "$FICHIER") octets" else echo "Erreur : Le fichier '$FICHIER' n'existe pas ou n'est pas un fichier régulier" fi fi if [ -n "$DOSSIER" ]; then if [ -d "$DOSSIER" ]; then echo "Traitement du répertoire : $DOSSIER" echo "Nombre de fichiers dans le répertoire : $(ls -1 "$DOSSIER" | wc -l)" else echo "Erreur : Le répertoire '$DOSSIER' n'existe pas ou n'est pas un répertoire" fi fi if [ -z "$FICHIER" ] && [ -z "$DOSSIER" ] && [ "$AIDE" = false ]; then echo "Aucun fichier ou répertoire spécifié. Utilisez -h ou --help pour obtenir des informations sur l'utilisation." fiRendez le script exécutable :
chmod +x file_processor.shCréons un fichier et un répertoire d'essai pour tester :
echo "Ceci est un fichier de test." > testfile.txt mkdir testdir touch testdir/file1.txt testdir/file2.txtExécutez le script avec différentes options :
./file_processor.sh -hLa sortie devrait montrer le message d'aide :
Usage :./file_processor.sh [-f|--file FICHIER] [-d|--directory DOSSIER] [-h|--help] Options : -f, --file FICHIER Spécifie un fichier à traiter -d, --directory DOSSIER Spécifie un répertoire à traiter -h, --help Affiche ce message d'aide./file_processor.sh -f testfile.txtSortie :
Traitement du fichier : testfile.txt Taille du fichier : 20 octets./file_processor.sh --directory testdirSortie :
Traitement du répertoire : testdir Nombre de fichiers dans le répertoire : 2./file_processor.sh -f testfile.txt -d testdirSortie :
Traitement du fichier : testfile.txt Taille du fichier : 20 octets Traitement du répertoire : testdir Nombre de fichiers dans le répertoire : 2
Points clés sur les options avec des arguments
Lorsqu'une option nécessite un argument, vous devez utiliser
shift 2au lieu de simplementshiftdans la structurecase. C'est parce que vous devez sauter à la fois l'option et son argument.L'argument de l'option est disponible sous la forme de
$2dans la structurecase(où$1est l'option elle-même).Vous devez valider les arguments fournis pour vos options (comme nous l'avons fait en vérifiant si le fichier/répertoire existe).
Fournir des messages d'erreur significatifs lorsque les arguments sont invalides est important pour la facilité d'utilisation.
Ce script démontre comment gérer les options avec des arguments, mais il a encore quelques limites. Dans l'étape suivante, nous ajouterons des fonctionnalités plus avancées telles que la validation de l'entrée et la gestion d'erreurs.
Ajout de fonctionnalités avancées et meilleures pratiques
Dans cette dernière étape, nous allons améliorer notre script avec des fonctionnalités plus avancées et suivre les meilleures pratiques pour créer des outils de ligne de commande robustes. Nous allons implémenter :
- Options requises avec validation
- Valeurs par défaut pour les options
- Une meilleure gestion des erreurs
- Traitement du contenu des fichiers
- Plusieurs arguments pour une seule option
Créons un script plus avancé qui démontre ces fonctionnalités :
Créez un nouveau fichier appelé
advanced_getopt.sh:touch advanced_getopt.shOuvrez le fichier dans l'éditeur et ajoutez le contenu suivant :
#!/bin/bash ## Fonction pour afficher les informations d'utilisation usage() { cat << EOF Usage: $0 [OPTIONS] [ARGUMENTS] Un script de démonstration montrant les fonctionnalités avancées de getopt. Options: -i, --input FILE Fichier d'entrée à traiter (requis) -o, --output FILE Fichier de sortie (par défaut : output.txt) -m, --mode MODE Mode de traitement : normal|verbose (par défaut : normal) -l, --log FILE Fichier de journal (par défaut : aucun) -v, --verbose Activer la sortie verbeuse -h, --help Afficher ce message d'aide Exemples: $0 -i input.txt -o output.txt $0 --input=data.csv --mode=verbose $0 -i input.txt -v -l log.txt EOF exit 1 } ## Fonction pour enregistrer des messages log_message() { local message="$1" local timestamp=$(date "+%Y-%m-%d %H:%M:%S") echo "[$timestamp] $message" if [ -n "$LOG_FILE" ]; then echo "[$timestamp] $message" >> "$LOG_FILE" fi } ## Fonction pour traiter un fichier process_file() { local input="$1" local output="$2" local mode="$3" if [! -f "$input" ]; then log_message "Erreur : Le fichier d'entrée '$input' n'existe pas." return 1 fi log_message "Traitement du fichier : $input" log_message "Fichier de sortie : $output" log_message "Mode : $mode" ## Effectuer différentes opérations selon le mode if [ "$mode" = "verbose" ]; then log_message "Détails du fichier :" log_message " - Taille : $(wc -c < "$input") octets" log_message " - Lignes : $(wc -l < "$input") lignes" log_message " - Mots : $(wc -w < "$input") mots" fi ## Simuler le traitement log_message "Lecture du fichier d'entrée..." cat "$input" > "$output" log_message "Traitement terminé." log_message "Sortie écrite dans : $output" return 0 } ## Analyser les options de ligne de commande OPTS=$(getopt -o i:o:m:l:vh --long input:,output:,mode:,log:,verbose,help -n 'advanced_getopt.sh' -- "$@") if [ $? -ne 0 ]; then echo "Échec de l'analyse des options" >&2 usage fi ## Remettre les paramètres positionnels aux options analysées eval set -- "$OPTS" ## Initialiser les variables avec les valeurs par défaut INPUT_FILE="" OUTPUT_FILE="output.txt" MODE="normal" LOG_FILE="" VERBOSE=false ## Traiter les options while true; do case "$1" in -i | --input) INPUT_FILE="$2" shift 2 ;; -o | --output) OUTPUT_FILE="$2" shift 2 ;; -m | --mode) if [ "$2" = "normal" ] || [ "$2" = "verbose" ]; then MODE="$2" else echo "Erreur : Mode invalide '$2'. Doit être 'normal' ou'verbose'." >&2 usage fi shift 2 ;; -l | --log) LOG_FILE="$2" shift 2 ;; -v | --verbose) VERBOSE=true shift ;; -h | --help) usage ;; --) shift break ;; *) echo "Erreur interne!" exit 1 ;; esac done ## Vérifier si les options requises sont fournies if [ -z "$INPUT_FILE" ]; then echo "Erreur : Le fichier d'entrée doit être spécifié avec l'option -i ou --input." >&2 usage fi ## Activer le mode verbeux si spécifié if [ "$VERBOSE" = true ] && [ "$MODE"!= "verbose" ]; then MODE="verbose" fi ## Traiter le fichier process_file "$INPUT_FILE" "$OUTPUT_FILE" "$MODE" EXIT_CODE=$? ## Les arguments supplémentaires sont disponibles sous la forme de $1, $2, etc. if [ $## -gt 0 ]; then log_message "Arguments supplémentaires fournis : $@" fi exit $EXIT_CODERendez le script exécutable :
chmod +x advanced_getopt.shCréez un fichier d'entrée d'essai :
cat > sample_input.txt << EOF Ceci est un fichier d'entrée d'essai. Il a plusieurs lignes. Nous allons l'utiliser pour tester notre script getopt avancé. Cela démontre le traitement de fichiers avec des scripts Bash. EOFExécutez le script avec différentes options :
./advanced_getopt.sh --helpLa sortie devrait montrer le message d'aide.
./advanced_getopt.sh -i sample_input.txtSortie :
[2023-XX-XX XX:XX:XX] Traitement du fichier : sample_input.txt [2023-XX-XX XX:XX:XX] Fichier de sortie : output.txt [2023-XX-XX XX:XX:XX] Mode : normal [2023-XX-XX XX:XX:XX] Lecture du fichier d'entrée... [2023-XX-XX XX:XX:XX] Traitement terminé. [2023-XX-XX XX:XX:XX] Sortie écrite dans : output.txt./advanced_getopt.sh -i sample_input.txt -v -l activity.logSortie :
[2023-XX-XX XX:XX:XX] Traitement du fichier : sample_input.txt [2023-XX-XX XX:XX:XX] Fichier de sortie : output.txt [2023-XX-XX XX:XX:XX] Mode : verbose [2023-XX-XX XX:XX:XX] Détails du fichier : [2023-XX-XX XX:XX:XX] - Taille : 151 octets [2023-XX-XX XX:XX:XX] - Lignes : 4 lignes [2023-XX-XX XX:XX:XX] - Mots : 28 mots [2023-XX-XX XX:XX:XX] Lecture du fichier d'entrée... [2023-XX-XX XX:XX:XX] Traitement terminé. [2023-XX-XX XX:XX:XX] Sortie écrite dans : output.txtVérifiez le fichier de journal et le fichier de sortie :
cat activity.logLa sortie devrait montrer tous les messages de journal.
cat output.txtLa sortie devrait montrer le contenu du fichier d'entrée.
Explication des fonctionnalités avancées
Revoyons les fonctionnalités avancées implémentées dans ce script :
Fonctions pour l'organisation :
usage()- Affiche des informations d'aidelog_message()- Gère la journalisation cohérenteprocess_file()- Encapsule la logique de traitement de fichier
Options requises :
- Le script vérifie si le fichier d'entrée requis est fourni et quitte avec une erreur si ce n'est pas le cas
Valeurs par défaut :
- Les valeurs par défaut sont définies pour les paramètres optionnels comme le fichier de sortie et le mode
Validation de l'entrée :
- Le script valide le paramètre de mode pour s'assurer qu'il est l'un des valeurs autorisées
- Il vérifie si le fichier d'entrée existe avant de le traiter
Capacité de journalisation :
- Les messages sont timestampés et peuvent être écrits dans un fichier de journal si spécifié
Gestion des erreurs :
- Le script utilise des codes de retour pour indiquer la réussite ou l'échec des opérations
- Il affiche des messages d'erreur utiles
Formats d'options flexibles :
- Les options courtes et longues sont prises en charge
- Le texte d'aide fournit des exemples d'utilisation
Meilleures pratiques pour getopt en Bash
Voici quelques meilleures pratiques à suivre lorsqu'on utilise getopt dans vos scripts Bash :
Toujours fournir de l'aide et des informations d'utilisation
- Inclure des exemples et des explications pour toutes les options
Utiliser à la fois les options courtes et longues
- Options courtes (comme
-f) pour les options courantes - Options longues (comme
--file) pour plus de clarté
- Options courtes (comme
Définir des valeurs par défaut pour les paramètres optionnels
- Initialiser les variables avant de traiter les options
Valider toute l'entrée de l'utilisateur
- Vérifier les options requises
- Valider les valeurs des options
- Vérifier l'existence du fichier avant de le traiter
Utiliser des fonctions pour organiser le code
- Rends le script plus lisible et maintenable
Gérer les erreurs de manière gracieuse
- Fournir des messages d'erreur utiles
- Utiliser des codes de sortie appropriés
Documenter votre script
- Inclure des commentaires expliquant la logique complexe
- Fournir des exemples d'utilisation
En suivant ces meilleures pratiques, vous pouvez créer des outils de ligne de commande robustes et conviviaux à l'aide de getopt en Bash.
Récapitulatif
Dans ce laboratoire, vous avez appris à utiliser l'utilitaire Bash getopt pour créer des interfaces de ligne de commande conviviales pour vos scripts. Vous êtes passé de la compréhension des arguments de base de ligne de commande à la mise en œuvre d'un parsing d'options avancé avec getopt.
Concepts clés abordés :
- Arguments de base de ligne de commande - Comprendre la manière dont Bash gère les paramètres positionnels
- Présentation de getopt - Apprendre la syntaxe et l'utilisation de base de getopt
- Gestion des options avec des arguments - Traiter les options qui nécessitent des valeurs supplémentaires
- Fonctionnalités avancées - Implémenter les options requises, les valeurs par défaut, la validation et la gestion appropriée des erreurs
Avec ces compétences, vous pouvez désormais créer des scripts Bash plus sophistiqués qui offrent une interface de ligne de commande professionnelle aux utilisateurs. Vos scripts peuvent gérer les options courtes et longues, valider l'entrée de l'utilisateur, fournir des messages d'erreur utiles et suivre les meilleures pratiques pour le développement d'outils de ligne de commande.
Ces connaissances sont applicables à de nombreux scénarios, allant des scripts utilitaires simples aux outils d'automatisation complexes. Les techniques que vous avez apprises vous aideront à rendre vos scripts plus conviviaux, robustes et faciles à maintenir.



