Comment gérer les commutateurs dans un script shell?

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 car getopts 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 que GETOPT_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.

Commentaires

  • La façon dont vous appelez options à la fin nest pas correct, il renverra -bash: syntax error near unexpected token $@. Appelez-le comme options "$@".
  • Oui, jai mélangé Perl et Bash. Corrigé.
  • Cette condition while ne doit pas être (($#)) à la place?
  • Pourquoi auriez-vous besoin de deux jeux de parenthèses pour $#? Modifier: vous ' avez raison. Correction du problème sur while (( "$#" ))

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *