Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente Dernière révision Les deux révisions suivantes | ||
utilisateurs:david5647:tutos:bash-gerer-les-parametres [24/03/2021 00:38] David5647 [Gestion des paramètres en bash] |
utilisateurs:david5647:tutos:bash-gerer-les-parametres [24/03/2021 17:16] David5647 [Introduction] |
||
---|---|---|---|
Ligne 8: | Ligne 8: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | Voici quelques exemples permettant de créer des scripts bash possédants une gestion plus fine des paramètres d'entrées qu'un simple $@. | + | Voici quelques exemples permettant de créer des scripts bash possédants une gestion plus fine des paramètres d'entrées plutôt que la simple utilisation de leur position ($1, $2, ...) |
Avec ces scripts, vous pourrez supporter : | Avec ces scripts, vous pourrez supporter : | ||
Ligne 18: | Ligne 18: | ||
- Des paramètres booléens | - Des paramètres booléens | ||
<code>./script -o</code> | <code>./script -o</code> | ||
+ | |||
Le détail de fonctionnement des scripts est inclut en commentaire. | Le détail de fonctionnement des scripts est inclut en commentaire. | ||
- | ==== Paramètre booléen ==== | + | ===== Paramètre booléen ===== |
=== Utilisation === | === Utilisation === | ||
Ligne 52: | Ligne 52: | ||
- | ==== Paramètre & valeur ==== | + | ===== Paramètre & valeur ===== |
=== Utilisation === | === Utilisation === | ||
Ligne 80: | Ligne 80: | ||
</file> | </file> | ||
- | ==== Tout type de paramètre ==== | + | ===== Paramètres nommé et court (-p) avec getopts ===== |
+ | |||
+ | **getopts** fait parti des buildins de bash, ce qui permet d'être sûr son implémentation (dès lors que l'on utilise bash) | ||
+ | |||
+ | **getopts** ne prend que des arguments courts (-p), qui peuvent accepter un paramètre | ||
+ | |||
+ | === Utilisation === | ||
+ | |||
+ | <code user>./getopts_simple.sh -v -a val_a -b val_b -o </code> | ||
+ | <code>a=val_a | ||
+ | b=val_b | ||
+ | option_o=true</code> | ||
+ | |||
+ | === Script === | ||
+ | |||
+ | <file bash getopts_simple.sh> | ||
+ | #!/bin/bash | ||
+ | |||
+ | # Paramètres "short" (-p) avec la build-in getopts | ||
+ | |||
+ | help_msg () { | ||
+ | echo "Usage: $(basename $0) [-h] [-v] [-a PARAM_A] [-b PARAM_B] [-o]" | ||
+ | echo 'Description' | ||
+ | echo ' -h display this help' | ||
+ | echo ' -v verbose' | ||
+ | echo ' -a PARAM_A Le paramètre A' | ||
+ | echo ' -b PARAM_B Le paramètre B' | ||
+ | echo ' -o option OPTION_O' | ||
+ | } | ||
+ | |||
+ | verbose_print () { # remplace un printf par un printf + condition | ||
+ | local MESSAGE="${@}" | ||
+ | if [[ "${VERBOSE}" == true ]];then # à condition que la variable globale $VERBOSE soit à true | ||
+ | printf "${MESSAGE}\n" | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | |||
+ | # Si aucun argument donné, on affiche l'aide | ||
+ | if [[ ${#} -eq 0 ]]; then | ||
+ | help_msg | ||
+ | exit 1 | ||
+ | fi | ||
+ | # Définition des paramètres | ||
+ | optstring=":hva:b:o" # getopts cherchera les paramètres listés ('-h', 'v', 'a',...) | ||
+ | # et attendra une valeur pour ceux suivis d'un ':' (-a value_a) | ||
+ | |||
+ | # Voici la liste des variables utilisées par getopts : | ||
+ | # OPTIND => index de l'argumetn | ||
+ | # OPTARG => valeur de l'option si définie ( -a option => OPTARG="option" ) | ||
+ | # OPTERR => 0 ou 1, si egal à 1, bash affiche les messages d'erreur (à 1 par défaut en début de boucle) | ||
+ | |||
+ | OPTION_O=false | ||
+ | |||
+ | # itère sur les paramètres type "-p", | ||
+ | while getopts ${optstring} arg ; do # ne prend pas en compte les positionnel (arg) | ||
+ | # ! le type long (--long) n'est pas accepté => cas '?)' | ||
+ | case ${arg} in | ||
+ | h) # Si $arg contient la valeur "h" | ||
+ | help_msg | ||
+ | exit 0 # Quitte sans erreur | ||
+ | ;; # fin du test, ne teste pas les arguments suivant => retour en début de boucle | ||
+ | v) | ||
+ | VERBOSE='true' # variable globale à true (lue dans verbose_print) | ||
+ | verbose_print "Mode prolixe activé." | ||
+ | ;; | ||
+ | a) # Si $arg contient la valeur "a" | ||
+ | PARAM_A="${OPTARG}" # getopts a défini la variable $OPTARG qui contient le paramètre succédant à "-a" | ||
+ | ;; | ||
+ | b) | ||
+ | PARAM_B="${OPTARG}" # même chose | ||
+ | ;; | ||
+ | o) | ||
+ | OPTION_O='true' # On ne demande pas de valeur, on passe simplement la variable à true si l'option est présente | ||
+ | ;; | ||
+ | ?) # l'arugment n'a pas été défini | ||
+ | echo "Option invalide: -${OPTARG}." | ||
+ | echo | ||
+ | help_msg | ||
+ | echo | ||
+ | ;; | ||
+ | esac | ||
+ | done | ||
+ | |||
+ | printf "a=$PARAM_A \nb=$PARAM_B \noption_o=$OPTION_O\n" | ||
+ | verbose_print "\nMessage si et seulement si drapeau '-v'" | ||
+ | </file> | ||
+ | |||
+ | ===== Paramètres nommé et court (-p) et arguments positionnels avec getopts ===== | ||
+ | |||
+ | **getops** ne gère pas les arguments positionnels, ce script permet leur implémentation | ||
+ | |||
+ | === Utilisation === | ||
+ | |||
+ | <code user>./get_opt_example.sh -v pos_1 -a val_a -b val_b -o pos_2 | ||
+ | </code> | ||
+ | <code>Mode prolixe activé. | ||
+ | a=val_a | ||
+ | b=val_b | ||
+ | option_o=true | ||
+ | positionnal= pos_1 pos_2</code> | ||
+ | |||
+ | === Script === | ||
+ | |||
+ | <file bash nom.sh> | ||
+ | optstring=":hva:b:o" | ||
+ | |||
+ | OPTION_O=false | ||
+ | while [ $# -gt 0 ]; do # Tant que $@ contient des éléments | ||
+ | |||
+ | unset OPTIND # on supprime les variables $OPTIND (position de l'argument suivant dans $@) | ||
+ | unset OPTARG # et $OPTARG définies dans le précédent tour de boucle | ||
+ | |||
+ | while getopts ${optstring} arg; do # Même chose que précédemment | ||
+ | case ${arg} in | ||
+ | h) | ||
+ | help_msg | ||
+ | exit 0 | ||
+ | ;; | ||
+ | v) | ||
+ | VERBOSE='true' | ||
+ | verbose_print "Mode prolixe activé." | ||
+ | ;; | ||
+ | a) | ||
+ | PARAM_A="${OPTARG}" | ||
+ | ;; | ||
+ | b) | ||
+ | PARAM_B="${OPTARG}" | ||
+ | ;; | ||
+ | o) | ||
+ | OPTION_O='true' | ||
+ | ;; | ||
+ | ?) | ||
+ | echo "Option invalide: -${OPTARG}." | ||
+ | echo | ||
+ | help_msg | ||
+ | echo | ||
+ | ;; | ||
+ | esac | ||
+ | done | ||
+ | |||
+ | # getopts itère jusqu'au premier argument positionnel | ||
+ | # (c-à-d qui n'est pas sous forme '-p' ou ne correspond pas à une valeur (-p valeur)) | ||
+ | # | ||
+ | # Si en début de tour, | ||
+ | # | ||
+ | # $@ = -a value_a -b value_b arg_1 ... | ||
+ | # | ||
+ | # optargs s’arrête à arg_1, | ||
+ | # on a traité 4 arguments : '-a', 'value_a', 'b' et "value_b', et getopts à défini | ||
+ | # | ||
+ | # OPTIND = 5 | ||
+ | # | ||
+ | # le prochain argument à traiter | ||
+ | # | ||
+ | |||
+ | shift $((OPTIND-1)) # On consomme 5-1 arguments avec le "shift", la liste des arguments $@ devient: | ||
+ | # | ||
+ | # $@ = arg_1 ... | ||
+ | |||
+ | ARGS="${ARGS} $1 " # L'argument positionnel se retrouve en $1 | ||
+ | shift # Une fois récupéré, on le consomme et on recommence la boucle jusqu'à ce qu'il n'y ai plus d'arguments | ||
+ | |||
+ | done | ||
+ | |||
+ | printf "a=$PARAM_A \nb=$PARAM_B \noption_o=$OPTION_O \npositionnal=$ARGS\n" | ||
+ | verbose_print "Message si drapeau '-v'" | ||
+ | </file> | ||
+ | |||
+ | ===== Tout type de paramètre ===== | ||
+ | |||
+ | Pour permettre l'utilisation d'argument long (--long) ou créer une implémentation compatible POSIX, | ||
+ | on peut se passer de getopts. | ||
=== Utilisation === | === Utilisation === | ||
Ligne 98: | Ligne 270: | ||
help_msg () { | help_msg () { | ||
- | echo """ | + | printf """ |
usage: script [-h] [-o] [-a NAMED_A] [-b NAMED_B] | usage: script [-h] [-o] [-a NAMED_A] [-b NAMED_B] | ||
Ligne 122: | Ligne 294: | ||
# $@ = "value_a --long_b value_b" | # $@ = "value_a --long_b value_b" | ||
# | # | ||
- | # $# compte le nombre d'argument restants, et parconséquent est réduit de 1 à chaque "shift" | + | # $# compte le nombre d'argument restants, et par conséquent est réduit de 1 à chaque "shift" |
Ligne 128: | Ligne 300: | ||
# Soit la commande: | # Soit la commande: | ||
# | # | ||
- | # ./script.sh -a value_a --long_b value_b -o positionnal | + | # ./script.sh -a value_a --long_b value_b -o positional |
# | # | ||
- | # La variable $@ contient alors "-a value_a --long_ value_b -o positionnal" | + | # La variable $@ contient alors "-a value_a --long_ value_b -o positional" |
Ligne 141: | Ligne 313: | ||
case $key in # Teste $key pour les cas suivant: | case $key in # Teste $key pour les cas suivant: | ||
-h|--help) | -h|--help) | ||
- | help_msg # execute la fonction help () | + | help_msg # exécute la fonction help () |
exit 0 # et quitte le script | exit 0 # et quitte le script | ||
;; | ;; | ||
-a|--long_a) # la clé "-a" est reconnue | -a|--long_a) # la clé "-a" est reconnue | ||
PARAM_A="$2" # la valeur du paramètre PARAM_A vient juste après, soit $2 | PARAM_A="$2" # la valeur du paramètre PARAM_A vient juste après, soit $2 | ||
- | shift # consomme un arguement, $@ ne contient plus que "value_a -b value_b" | + | shift # consomme un argument, $@ ne contient plus que "value_a -b value_b" |
- | shift # consomme un deuxième arguement, $@ = "-b value_b" | + | shift # consomme un deuxième argument, $@ = "-b value_b" |
;; # On peut passer au tour suivant, avec $key prenant la valeur $1, soit "-b" | ;; # On peut passer au tour suivant, avec $key prenant la valeur $1, soit "-b" | ||
-b|--long_b) # (2e tour) : $key à la valeur "-b" et est reconnue | -b|--long_b) # (2e tour) : $key à la valeur "-b" et est reconnue | ||
Ligne 164: | Ligne 336: | ||
else # Si la clé commence par "-" | else # Si la clé commence par "-" | ||
echo "Argument non défini : '$key'" # C'est quelle ne fait pas partie de la liste définie plus haut | echo "Argument non défini : '$key'" # C'est quelle ne fait pas partie de la liste définie plus haut | ||
- | exit 1 # On arrète le programme | + | exit 1 # On arrête le programme |
fi | fi | ||
esac | esac | ||
- | done # FIN! Biensûr l'exemple est arrangé dans le "bon ordre", mais la position des arguments n'a pas d'importance. | + | done # FIN! Bien-sûr l'exemple est arrangé dans le "bon ordre", mais la position des arguments n'a pas d'importance. |
# Paramètres parsés | # Paramètres parsés | ||
- | echo "positional : $POSITIONAL" # Contient : "positionnal" | + | printf "positional : $POSITIONAL \n" # Contient : "positional" |
- | echo "param_a : $PARAM_A" # Contient : "value_a" | + | printf "param_a : $PARAM_A \n" # Contient : "value_a" |
- | echo "param_b : $PARAM_B" # Contient : "value_b" | + | printf "param_b : $PARAM_B \n" # Contient : "value_b" |
- | echo "option_o : $OPTION_O" # Contient : "true" | + | printf "option_o : $OPTION_O \n" # Contient : "true" |
</file> | </file> | ||
Ligne 179: | Ligne 351: | ||
- | ==== Séparer les paramètres ==== | + | ===== Séparer les paramètres ===== |
- | Dans le cas de paramètres inconnus à l'avance, ou pour un script plus leger, cette fonction permet de trier les différnet arguments en fonction de leur type supposé (positional(//arg//), named (//-n arg//), option (//-o//)) et les stocke dans 3 variables différentes. | + | Dans le cas de paramètres inconnus à l'avance, ou pour un script plus leger, cette fonction permet de trier les différents arguments en fonction de leur type supposé (positional(//arg//), named (//-n arg//), option (//-o//)) et les stocke dans 3 variables différentes. |
A defaut, un groupe `-n arg` est considéré comme **named** et non comme un **option** + **positional** | A defaut, un groupe `-n arg` est considéré comme **named** et non comme un **option** + **positional** |