Existe-t-il des outils intégrés qui reconnaissent -x
et --xxxx
comme commutateurs, et non comme arguments, ou devez-vous parcourir toutes les variables dentrée, tester les tirets, puis analyser les arguments par la suite?
Réponse
Utilisez getopts
.
Cest assez portable tel quil est dans la spécification POSIX. Malheureusement, il ne prend pas en charge les options longues.
Voir aussi ce getopts
tutoriel gracieuseté de le wiki bash-hackers et cette question de stackoverflow.
Si vous navez besoin que doptions courtes, modèle dutilisation typique pour getopts
(en utilisant un rapport derreur non silencieux) est:
# process arguments "$1", "$2", ... (i.e. "$@") while getopts "ab:" opt; do case $opt in a) aflag=true ;; # Handle -a b) barg=$OPTARG ;; # Handle -b argument \?) ;; # Handle error: unknown option or missing required argument. esac done
Commentaires
- Il convient de mentionner que
getopt
doit toujours être vérifié comme GNU getopt avant de lutiliser, mais vous ne devriez pas ' lutiliser quand même cargetopts
est de toute façon plus portable (et généralement plus agréable). Si vous avez besoin de lappeler pour une raison quelconque, appelez-le dune manière spécifique à GNU, et assurez-vous queGETOPT_COMPATIBLE
ne se trouve pas dans lenvironnement. - Que fait le signe deux-points dans
while getopts "ab:" opt
? - @ user394 Le
:
après une lettre doption le signifie nécessite un argument. Un:
comme premier caractère signifie supprimer les messages derreur.
Réponse
Je suppose que vous « utilisez bash ou similaire. Un exemple:
all=false long=false while getopts ":hal" option; do case $option in h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;; a) all=true ;; l) long=true ;; ?) echo "error: option -$OPTARG is not implemented"; exit ;; esac done # remove the options from the positional parameters shift $(( OPTIND - 1 )) ls_opts=() $all && ls_opts+=( -a ) $long && ls_opts+=( -l ) # now, do it ls "${ls_opts[@]}" "$@"
Commentaires
- +1 pour utiliser
+=
avec un tableau. Je ' je ne savais pas que vous pouviez faire ça. Bien!
Réponse
Vous devez écrire un cycle pour analyser les paramètres. En effet, vous pouvez utiliser getopts
pour le faire facilement.
Voici un exemple simple tiré de la page de manuel getopts
:
aflag= bflag= while getopts ab: name do case $name in a) aflag=1;; b) bflag=1 bval="$OPTARG";; ?) printf "Usage: %s: [-a] [-b value] args\n" $0 exit 2;; esac done if [ ! -z "$aflag" ]; then printf "Option -a specified\n" fi if [ ! -z "$bflag" ]; then printf "Option -b "%s" specified\n" "$bval" fi shift $(($OPTIND - 1)) printf "Remaining arguments are: %s\n" "$*"
Réponse
Jai récemment écrit un script pour mon travail qui était polyvalent et autorisait plusieurs types de commutateurs dans nimporte quel ordre. Je ne peux « t divulguez le script complet pour des raisons juridiques évidentes (sans oublier que je ne lai pas avec moi pour le moment), mais en voici lessentiel .. vous pouvez le mettre i n un sous-programme et appelez-le à la fin de votre script:
options () { if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist while (( "$#" )); do # process ALL arguments if [ "$1" = ^-t$ ]; then # -t short for "test" # do something here THEN shift the argument # shift removes it from $@ and reduces $# by # one if you supply no argument shift # we can also process multiple arguments at once elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments # do something more then remove them ALL from the arg list shift 3 else echo "No matching arguments!" echo "Usage: [script options list here]" fi done else echo "Usage: [script options list here]" exit 0 fi } options "$@" # run options and loop through/process ALL arguments
Je recommande de limiter votre script bash à moins de 400 lignes / 15k caractères; mon script susmentionné a dépassé cette taille et est devenu très difficile à travailler. Jai commencé à le réécrire en Perl, ce qui est bien mieux adapté à la tâche. Gardez cela à lesprit lorsque vous travaillez sur vos scripts dans bash. Bash est idéal pour les petits scripts et les oneliners, mais tout ce qui est plus complexe et il vaut mieux lécrire en Perl.
Remarque, je nai pas testé ce qui précède, donc ça ne marche probablement pas, mais vous en tirez lidée générale.
options
à la fin nest pas correct, il renverra-bash: syntax error near unexpected token $@
. Appelez-le commeoptions "$@"
.while
ne doit pas être(($#))
à la place?$#
? Modifier: vous ' avez raison. Correction du problème surwhile (( "$#" ))