Je veux appeler le myscript
fichier de cette façon:
$ ./myscript -s 45 -p any_string
ou
$ ./myscript -h #should display help
$ ./myscript #should display help
Mes exigences sont:
getopt
ici pour obtenir les arguments d'entrée- vérifier qu'il
-s
existe, sinon renvoyer une erreur - vérifier que la valeur après le
-s
est 45 ou 90 - vérifier que le
-p
existe et qu'il y a une chaîne d'entrée après - si l'utilisateur entre
./myscript -h
ou./myscript
affiche alors l'aide
J'ai essayé jusqu'à présent ce code:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Mais avec ce code, j'obtiens des erreurs. Comment faire avec Bash et getopt
?
-s
, faire un argument de position:./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
c'est en fait une option (c'est-à-dire que votre programme peut continuer s'il n'est pas présent). Dans ce cas./myscript 45 -p any_string
,. (Je pense que celagetopt
peut gérer des options mixtes et des arguments positionnels, alors que labash
commande intégréegetopts
nécessite que tous les arguments positionnels soient placés après les options.)Réponses:
L'exemple s'exécute:
la source
usage()
vraiment renvoyer 1?-h
il devrait revenir0
, en frappant un indicateur inexistant, il devrait revenir>0
(pour des raisons de simplicité, je n'ai pas fait de différence entre ces cas et personne ne vous oblige à imprimer le texte d'utilisation dans ce dernier cas) . J'ai vu des programmes qui reviennent toujours!= 0
, même sur-h/--help
. Peut-être que je devrais mettre à jour l'extrait au cas où les gens l'utilisent comme passe-partout (j'espère que non)?getopts
') conception, il n'y a pas de "arguments optionnels" avecgetopts
. L'analyseur ne peut tout simplement pas savoir si le prochain jeton est un argument de l'option actuelle ou une option en soi car il-p
pourrait s'agir de la valeur souhaitée. Vous pouvez contourner cela si vous savez absolument qu'un paramètre d'option ne peut pas ressembler à une autre option valide, oui, mais on pourrait dire qu'il y a une raison pour laquelle les arguments facultatifs ne sont pas définis dans POSIX.bash
lexer à identifier les variables. Dans de nombreux cas, ils sont inutiles et le fait que je les utilise toujours n'est qu'une question de style de codage personnel. Pour moi, il est plus facile (et plus joli) de toujours les utiliser au lieu de se souvenir des règles d'analyse en ce qui concerne l'ambiguïté. À peu près la même raison pour laquelle on écriraitif (foo) { bar; }
au lieu deif (foo) bar;
dans un langage de style C (esthétique et / ou éviter les erreurs stupides).Le problème avec le code d'origine est que:
h:
attend un paramètre où il ne devrait pas, alors changez-le en justeh
(sans deux-points)-p any_string
, vous devez ajouterp:
à la liste des argumentsFondamentalement,
:
après que l'option signifie qu'elle nécessite l'argument.La syntaxe de base de
getopts
est (voir:)man bash
:où:
OPTSTRING
est une chaîne avec la liste des arguments attendus,h
- vérifier l'option-h
sans paramètres; donne une erreur sur les options non prises en charge;h:
- vérifier l'option-h
avec le paramètre; donne des erreurs sur les options non prises en charge;abc
- vérification des options-a
,-b
,-c
; donne des erreurs sur les options non prises en charge;:abc
- vérification des options-a
,-b
,-c
; réduit au silence les erreurs sur les options non prises en charge;Remarques: En d'autres termes, deux points devant les options vous permettent de gérer les erreurs dans votre code. La variable contiendra
?
dans le cas d'une option non prise en charge,:
dans le cas d'une valeur manquante.OPTARG
- est défini sur la valeur d'argument actuelle,OPTERR
- indique si Bash doit afficher des messages d'erreur.Le code peut donc être:
Exemple d'utilisation:
Voir: Petit tutoriel getopts sur Bash Hackers Wiki
la source
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Il ne prend en compte qu'un seul espace blanc avant l'option lettre, supprime le # du commentaire et ajoute un «-» avant l'option lettre pour le rendre plus clair pour la commande.:
je n'ai pas pu obtenir le bon avant d'avoir vu ces notes. Nous devons ajouter un:
aux options où nous attendons un argument.Utilisation
getopt
Pourquoi getopt?
Analyser les arguments de ligne de commande élaborés pour éviter toute confusion et clarifier les options que nous analysons afin que le lecteur des commandes puisse comprendre ce qui se passe.
Qu'est-ce que Getopt?
getopt
est utilisé pour décomposer (analyser) les options dans les lignes de commande pour une analyse facile par les procédures shell et pour vérifier les options légales. Il utilise lesgetopt(3)
routines GNU pour ce faire.getopt
peut avoir les types d'options suivants.Remarque: Dans ce document, lors de l'explication de la syntaxe:
COMMENT UTILISER
getopt
?Syntaxe: premier formulaire
Exemples:
Ici h, v, t sont les options et -h -v -t est la façon dont les options doivent être données en ligne de commande.
Dans param facultatif, la valeur ne peut pas avoir de séparation d'espaces avec l'option. Ainsi, dans l'exemple "-t123", -t est l'option 123 est la valeur.
Syntaxe: deuxième formulaire
Ici, après getopt est divisé en cinq parties
Exemples
Syntaxe: troisième forme
Ici, après getopt est divisé en cinq parties
Exemples
GETOPT_OPTIONS
getopt_options change la façon dont les paramètres de ligne de commande sont analysés.
Voici quelques-unes des options getopt_options
Option: -l ou --longoptions
Par exemple,
--name=Karthik
une longue option est envoyée en ligne de commande. Dans getopt, l'utilisation des options longues est commePuisque le nom: est spécifié, l'option doit contenir une valeur
Option: -a ou --alternative
Par exemple, au lieu de
--name=Karthik
vous pouvez utiliser simplement-name=Karthik
Un exemple de script complet avec le code:
Exécution de ce fichier script:
la source
L'exemple fourni avec
getopt
(ma distribution l'a mis/usr/share/getopt/getopt-parse.bash
) semble couvrir tous vos cas:la source
Je sais que cela a déjà été répondu, mais pour le compte rendu et pour toute personne ayant les mêmes exigences que moi, j'ai décidé de poster cette réponse connexe. Le code est inondé de commentaires pour expliquer le code.
Réponse mise à jour:
Enregistrez le fichier sous
getopt.sh
:Ensuite, vous pouvez l'utiliser comme ceci:
Ancienne réponse:
J'ai récemment eu besoin d'utiliser une approche générique. Je suis tombé sur cette solution:
Je n'ai pas testé cela grossièrement, donc je pourrais avoir des bugs là-dedans.
la source
getopts
une fonction, ajoutezlocal OPTIND OPTARG
à la fonctiongetopts
Exemple POSIX 7
Il convient également de vérifier l'exemple de la norme: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
Et puis nous pouvons l'essayer:
Testé dans Ubuntu 17.10,
sh
est le tiret 0.5.8.la source
"getops" et "getopt" sont très limités. Bien que "getopt" soit suggéré de ne pas être utilisé du tout, il offre de longues options. Où "getopts" n'autorise que les options de caractère unique telles que "-a" "-b". Il y a quelques inconvénients supplémentaires lors de l'utilisation de l'un ou l'autre.
J'ai donc écrit un petit script qui remplace "getopts" et "getopt". C'est un début, il pourrait probablement être beaucoup amélioré.
Mise à jour 08-04-2020 : j'ai ajouté la prise en charge des traits d'union, par exemple "--package-name".
la source