web-dev-qa-db-fra.com

Comment puis-je détecter qu'aucune option n'a été passée avec getopts?

J'ai ce code -

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
done
print 'hi'$name

Quand je cours bash getoptDemos.sh (sans l'option) IT imprime hi au lieu d'appeler la fonction usage. Il appelle l'utilisation lorsque des options autres que W, H et L sont données. Ensuite, vous ne pouvez pas fonctionner quand aucune option n'est spécifiée.

J'ai essayé d'utiliser ?, \?, : au lieu de * Mais je ne peux pas réaliser ce que je voulais. Je veux dire tout le docs sur getopt dit qu'il utilisera ?.

Qu'est-ce que je fais mal?

19
Hussain Tamboli

Lorsque vous exécutez ce script sans option, GetOPT reviendra FALSE, de sorte qu'il n'entrera pas du tout la boucle. Il va juste tomber à l'impression - est-ce ksh/zsh?

Si vous devez avoir une option, votre meilleur pari est de tester $ Nom après la boucle.

if [ -z "$name" ]
then
   usage
   exit
fi

Mais assurez-vous que $name était vide avant d'appeler getopts (comme il aurait pu être $name Dans l'environnement, la coquille reçue au démarrage) avec

unset name

(avant la boucle getopts)

16
Julian

getopts traite les options à son tour. C'est son travail. Si l'utilisateur n'accepte aucune option, la première invocation de getopts sort la boucle tandis que.

Si aucune des options ne prend un argument, la valeur de OPTIND indique combien d'options ont été transmises. En général, OPTIND est le nombre d'arguments qui sont des options ou des arguments aux options, par opposition aux arguments non options (opérandes).

while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"

En tout état de cause, vous n'essayez pas de déterminer s'il n'y avait aucune option, mais si aucune des options de définition name a été transmise. Donc Vérifiez si name est non défini (et prenez soin de vous désiertoire d'abord .

Si votre script doit recevoir des arguments d'option est tout cas, placez ce bloc au début (avant GETOPS).

if [[ ! $@ =~ ^\-.+ ]]
then
  #display_help;
fi

Vérifications de blocs que la chaîne de paramètre ne commence pas avec - Symbole, ce qui indique que le premier paramètre n'est pas un argument d'option.

4
mcounad

Je voudrais vérifier avec une variable. Si les getopts ne transmet jamais la boucle en cas d'aucun argument, vous pouvez l'utiliser par exemple comme celui-ci:

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}

no_args="true"
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
    no_args="false"
done

[[ "$no_args" == "true" ]] && { usage; exit 1; }

print 'hi'$name
2
Imre Kneifel

Juste avant votre bloc getopts Block, vérifiez s'il vous plaît si $1 (le premier argument/option que vous avez transmis sur la ligne de commande) est égal à une chaîne vide. Si c'est le cas, imprimez le message d'utilisation et quittez-le, (ou exécutez des fonctions "Aucune option" si vous êtes un anarchiste), sinon laissez getopts analysez les options telles que Normal.

La raison pour laquelle cette fonctionnalité n'est pas incluse dans les getopts, c'est parce que vous pouvez déjà y accomplir dans Bash avec un "if-sinon". Exemple:

if [[ $1 == "" ]]; then
    Your_Usage_Function;
    exit;
else
   #parse options with getopts code block here;
fi

Avoir un sens?

0
codrcodz