Les getopts Bash doivent permettre aux options et arguments de ne pas dépendre de la position, comme indiqué dans tutorials et docs.bash getopts ignore les options sauf si elles sont spécifiées d'une certaine manière
L'extrait de code suivant peut recevoir deux options:
- une option de débogage -d qui nécessite un argument
- une option -f force de , sans arguments.
Je vois le comportement étrange que seule la première option répertoriée est traitée correctement.
#!/bin/bash
## Defaults
DEBUG=INFO
forceOption=FALSE
## Usage
printUsage() {
echo " "
echo "USAGE: $0 [-d <DEBUG_LEVEL>] [ -f ]"
echo " "
exit 1
}
#
## Manage options before start
#
while getopts "hfd:" OPT
do
case $OPT in
h) printUsage ;;
f) forceOption="TRUE" ;;
d) debugLevel="$OPTARG" ;;
*) printUsage ;;
esac
shift `expr $OPTIND - 1`
done
if [ -n "$debugLevel" ] ; then
DEBUG="$debugLevel"
fi
echo "DEBUG : $DEBUG"
echo "Force : $forceOption"
Vous pouvez voir le comportement défectueux ci-dessous:
[rgulia$ ~] ./getopts.sh -d WARNING -f
DEBUG : WARNING
Force : FALSE
[rgulia$ ~] ./getopts.sh -f -d WARNING
DEBUG : INFO
Force : TRUE
Le code correctement lorsque les parse options sont utilisées séparément ou si -f précède -d dans la liste des options et ils sont attachés les uns aux autres
[rgulia$ ~] ./getopts.sh -f
DEBUG : INFO
Force : TRUE
[rgulia$ ~] ./getopts.sh -d WARNING
DEBUG : WARNING
Force : FALSE
[rgulia$ ~] ./getopts.sh -fd WARNING
DEBUG : WARNING
Force : TRUE
Mon impression est que la boucle sort trop tôt b parce qu'elle ne parvient pas à calculer correctement OPTIND quand une option est passée à un argument.
J'ai fait quelques tracés avec des instructions printf pour les valeurs de OPT, OPTARG et OPTIND confirme une telle théorie, mais je ne comprends toujours pas pourquoi cela se passe et comment le réparer.
Des suggestions?
Vous avez raison! Ça marche. Je pense que j'avais mal compris la signification de OPTIND tout le long. Donc, getopts garde trace de l'option et des arguments lus dans la boucle et la décrémentation d'OPTIND est seulement de faire savoir à ce shell combien d'arguments sont restés dans le vecteur arg une fois que -d et -f sont traités, non? – rgulia
oui. Personnellement, j'ai arrêté d'utiliser le style getopts pour les arguments. Il a été conçu pour être laconique (à un moment où "copier" était trop long, d'où "cp") et quand la plupart des autres OS majeurs (MSDOS, VMS, RSTS) utilisaient 'command/option = value ..." ' # mais Unix a utilisé "/" dans les chemins, donc il est passé à "-o value" Il est ridiculement facile (dans les scripts et les programmes) de balayer les args [] pour les chaînes de la forme 'option = value' ... utiliser également les paramètres par défaut définis dans l'environnement My 2c – Mischa
Merci beaucoup pour l'explication! – rgulia