Bash getopts: lire $ OPTARG pour les drapeaux optionnels?
J'aimerais être en mesure d'accepter à la fois obligatoires et facultatives les drapeaux dans mon script. Voici ce que j'ai jusqu'à présent.
#!bin/bash
while getopts ":a:b:cdef" opt; do
case $opt in
a ) APPLE="$OPTARG";;
b ) BANANA="$OPTARG";;
c ) CHERRY="$OPTARG";;
d ) DFRUIT="$OPTARG";;
e ) EGGPLANT="$OPTARG";;
f ) FIG="$OPTARG";;
\?) echo "Invalid option: -"$OPTARG"" >&2
exit 1;;
: ) echo "Option -"$OPTARG" requires an argument." >&2
exit 1;;
esac
done
echo "Apple is "$APPLE""
echo "Banana is "$BANANA""
echo "Cherry is "$CHERRY""
echo "Dfruit is "$DFRUIT""
echo "Eggplant is "$EGGPLANT""
echo "Fig is "$FIG""
Toutefois, la sortie de la suivante:
bash script.sh -a apple -b banana -c cherry -d dfruit -e eggplant -f fig
...sorties ceci:
Apple is apple
Banana is banana
Cherry is
Dfruit is
Eggplant is
Fig is
Comme vous pouvez le voir, les indicateurs facultatifs ne sont pas en tirant les arguments $OPTARG comme il le fait avec les drapeaux. Est-il un moyen de lire $OPTARG sur les indicateurs facultatifs sans se débarrasser de la nlfa ":)" erreur de manipulation?
=======================================
EDIT: je me suis retrouvé en suivant les conseils de Gilbert ci-dessous. Voici ce que j'ai fait:
#!/bin/bash
if [[ "$1" =~ ^((-{1,2})([Hh]$|[Hh][Ee][Ll][Pp])|)$ ]]; then
print_usage; exit 1
else
while [[ $# -gt 0 ]]; do
opt="$1"
shift;
current_arg="$1"
if [[ "$current_arg" =~ ^-{1,2}.* ]]; then
echo "WARNING: You may have left an argument blank. Double check your command."
fi
case "$opt" in
"-a"|"--apple" ) APPLE="$1"; shift;;
"-b"|"--banana" ) BANANA="$1"; shift;;
"-c"|"--cherry" ) CHERRY="$1"; shift;;
"-d"|"--dfruit" ) DFRUIT="$1"; shift;;
"-e"|"--eggplant" ) EGGPLANT="$1"; shift;;
"-f"|"--fig" ) FIG="$1"; shift;;
* ) echo "ERROR: Invalid option: \""$opt"\"" >&2
exit 1;;
esac
done
fi
if [[ "$APPLE" == "" || "$BANANA" == "" ]]; then
echo "ERROR: Options -a and -b require arguments." >&2
exit 1
fi
Merci beaucoup à tout le monde. Cela fonctionne parfaitement jusqu'à présent.
source d'informationauteur earth | 2013-08-24
Vous devez vous connecter pour publier un commentaire.
Plus coque getopts ont été ennuyeux moi pendant une longue période, y compris le manque de soutien des arguments optionnels.
Mais si vous êtes prêt à utiliser "--posix" style arguments, visite bash argument de cas pour args $@
:
signifie "prend un argument", pas "argument obligatoire". C'est, une option de caractère n'est pas suivie par:
signifie un pavillon de style option (sans argument), tandis qu'une option de caractère, suivi par:
s'entend d'une option avec un argument.Donc, vous voulez probablement
Si vous voulez "obligatoire" options (un peu un oxymore), vous pouvez vérifier après l'argument de l'analyse que votre option obligatoire valeurs ont été tous ensemble.
Il n'est pas facile... Tout "facultatif" les arguments d'option doit effectivement être nécessaire autant que
getopts
le savent. Bien sûr, en option, un argument doit être une partie de la même argument au script que l'option qui va avec. Sinon, une option-f
avec un argument optionnel et une option-a
avec un argument requis peuvent se confondre:La seule façon de le faire est de tester la validité de l'option et son argument sont dans le même argument au script. Si oui, OPTARG est l'argument de l'option. Sinon, 'OPTIND' doit être décrémenté de un. Bien sûr, l'option est maintenant nécessaire d'avoir un argument, ce personnage sera trouvé quand une option est manquant un argument. Suffit d'utiliser un autre
case
pour déterminer si toutes les options sont nécessaires:Ce qui a fonctionné pour moi jusqu'à présent.
Pour bash, c'est ma façon préférée de parse/support cli args. J'ai utilisé getopts et c'était trop frustrant qu'il ne supporterais pas longtemps options. J'aime la manière dont il fonctionne dans l'autre - en particulier pour les fonctionnalités intégrées.
Court, simple. Un ingénieur du son meilleur ami!
Je pense que cela peut être modifié à l'appui "--" options...
Encouragements =)
Compréhension
bash
'sgetopts
La
bash
page de manuel (en citant la version 4.1 manuel) pourgetopts
dit:Noter que:
Le premier colon de la chaîne d'option met
getopts
en mode silencieux; il ne génère pas de message d'erreur.La description ne mentionne rien à propos de l'option l'option arguments.
Je suis en supposant que vous êtes après de la fonctionnalité semblable à:
où le drapeau
f
(-f
) accepte éventuellement un argument. Ce n'est pas pris en charge parbash
'sgetopts
de commande. La fonction POSIXgetopt()
à peine soutient que la notation. En effet, seule la dernière option sur une ligne de commande peut avoir un argument facultatif en vertu de la norme POSIX.Quelles sont les alternatives?
En partie, consulter À l'aide de
getopts
bash
script shell pour obtenir de longue et de courte options de ligne de commande.GNU
getopt
(au singulier!) le programme est un complexe beastie qui prend en charge à long et à court d'options et prend en charge les arguments facultatifs pour les longs options (et utilise GNUgetopt(3)
. Le suivi de sa source, c'est divertissant; le lien sur la page d'die.net l'est pas; vous le trouverez dans un sous-répertoire ftp://ftp.kernel.org/pub/linux/utils/util-linux (sans le-ng
). Je n'ai pas retrouvé un emplacement à http://www.gnu.org/ ou http://www.fsf.org/ qui le contient.