Je voudrais utiliser getopts
dans une fonction que j'ai définie dans mon .bash_profile. L'idée est que j'aimerais passer quelques drapeaux à cette fonction pour modifier son comportement.
Voici le code:
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Quand je l'invoque comme ceci:
t -a bc
J'obtiens cette sortie:
-a bc
?
Qu'est-ce qui ne va pas? Je voudrais obtenir la valeur bc
sans décaler ni analyser manuellement. Comment utiliser correctement getopts
dans une fonction?
EDIT: corrigé mon extrait de code pour essayer $ OPTARG, en vain
EDIT # 2: OK s'avère que le code est bien, mon Shell a été en quelque sorte foiré. L'ouverture d'une nouvelle fenêtre l'a résolu. La valeur arg était en effet dans $ OPTARG.
Comme le souligne @Ansgar, l'argument de votre option est stocké dans ${OPTARG}
, mais ce n'est pas la seule chose à surveiller lors de l'utilisation de getopts
dans une fonction. Vous devez également vous assurer que ${OPTIND}
est local à la fonction en la désactivant ou en la déclarant local
, sinon vous rencontrerez un comportement inattendu lorsque vous invoquerez la fonction plusieurs fois.
t.sh
:
#!/bin/bash
foo()
{
foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }
local OPTIND o a
while getopts ":a:" o; do
case "${o}" in
a)
a="${OPTARG}"
;;
*)
foo_usage
;;
esac
done
shift $((OPTIND-1))
echo "a: [${a}], non-option arguments: $*"
}
foo
foo -a bc bar quux
foo -x
Exemple d'exécution:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
foo: [-a <arg>]
Si vous commentez # local OPTIND
, voici ce que vous obtenez à la place:
$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
a: [bc], non-option arguments:
En dehors de cela, son utilisation est la même que lorsqu'elle est utilisée en dehors d'une fonction.
Voici un exemple simple d'utilisation de getopts
dans la fonction Shell:
#!/usr/bin/env bash
t() {
local OPTIND
getopts "a:" OPTION
echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo
Production:
$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo
Comme @ a souligné Adrian , local OPTIND
(ou OPTIND=1
) doit être défini car Shell ne réinitialise pas OPTIND
automatiquement entre plusieurs appels à getopts
(man bash
).
La syntaxe de base pour getopts
est:
getopts OPTSTRING VARNAME [ARGS...]
et par défaut, ne pas spécifier d'arguments équivaut à l'appeler explicitement avec "$ @" qui est: getopts "a:" opts "$@"
.
En cas de problème, voici les variables utilisées par getopts
pour vérifier:
OPTIND
- l'index de l'argument suivant à traiter,OPTARG
- la variable est définie sur n'importe quel argument pour une option trouvée par getopts
,OPTERR
(pas POSIX) - défini sur 0 ou 1 pour indiquer si Bash doit afficher les messages d'erreur générés par getopts
.De plus, voir: Petit tutoriel getopts sur le wiki Bash Hackers
L'argument est stocké dans la variable $OPTARG
.
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
Production:
$ t -a bc
-a bc
a
bc