Gibt es einige integrierte Tools, die -x
und --xxxx
als Schalter und nicht als Argumente, oder müssen Sie alle Eingabevariablen durchgehen, nach Bindestrichen suchen und anschließend die Argumente analysieren?
Antwort
Verwenden Sie getopts
.
Es ist fair tragbar wie es in der POSIX-Spezifikation ist. Leider werden lange Optionen nicht unterstützt.
Siehe auch dieses getopts
Tutorial mit freundlicher Genehmigung von das Bash-Hacker-Wiki und diese Frage aus dem Stackoverflow.
Wenn Sie nur kurze Optionen benötigen, typisches Verwendungsmuster für getopts
(unter Verwendung einer nicht stillen Fehlerberichterstattung) lautet:
# 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
Kommentare
- Es sollte erwähnt werden, dass
getopt
immer als GNU getopt überprüft werden sollte, bevor Sie es verwenden, aber Sie sollten es ' trotzdem nicht verwenden dagetopts
ohnehin portabler (und im Allgemeinen besser) ist. Wenn Sie es aus irgendeinem Grund aufrufen müssen, rufen Sie es auf GNU-spezifische Weise auf. und stellen Sie sicher, dass sichGETOPT_COMPATIBLE
nicht in der Umgebung befindet. - Was macht der Doppelpunkt in
while getopts "ab:" opt
? - @ user394 Die
:
nach einem Optionsbuchstaben kennzeichnet dies erfordert ein Argument. Ein:
als erstes Zeichen bedeutet, Fehlermeldungen zu unterdrücken.
Antwort
Ich gehe davon aus, dass Sie Bash oder ähnliches verwenden. Ein Beispiel:
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[@]}" "$@"
Kommentare
- +1 für die Verwendung von
+=
mit einem Array. ' wusste nicht, dass Sie das tun können. Schön!
Antwort
Sie müssen einen Zyklus schreiben, um die Parameter zu analysieren. In der Tat können Sie getopts
, um dies einfach zu tun.
Dies ist ein einfaches Beispiel aus der getopts
Handbuchseite:
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" "$*"
Antwort
Ich habe kürzlich ein Skript für Arbeiten geschrieben, das vielseitig ist und mehrere Arten von Schaltern in beliebiger Reihenfolge zulässt. Ich kann nicht Geben Sie das vollständige Skript aus offensichtlichen rechtlichen Gründen bekannt (ganz zu schweigen davon, dass ich es im Moment nicht bei mir habe), aber hier ist das Fleisch davon. Sie können es sagen, ich n eine Unterroutine und rufen Sie sie am Ende Ihres Skripts auf:
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
Ich empfehle, Ihr Bash-Skript auf weniger als 400 Zeilen / 15.000 Zeichen zu beschränken. Mein oben genanntes Skript wuchs über diese Größe hinaus und es wurde sehr schwierig, daran zu arbeiten. Ich habe angefangen, es in Perl umzuschreiben, was für die Aufgabe viel besser geeignet ist. Denken Sie daran, wenn Sie in bash an Ihren Skripten arbeiten. Bash ist ideal für kleine Skripte und Oneliner, aber alles, was komplexer ist, und Sie sollten es besser in Perl schreiben.
Beachten Sie, dass ich das Obige nicht getestet habe, also funktioniert es wahrscheinlich nicht, aber Sie erhalten eine allgemeine Vorstellung davon.
Kommentare
- So wie Sie am Ende
options
aufrufen ist nicht korrekt, es wird-bash: syntax error near unexpected token $@
zurückgegeben. Nennen Sie es alsoptions "$@"
. - Ja, ich habe Perl und verwechselt Bash. Korrigiert.
- Diese
while
Bedingung sollte nicht stattdessen(($#))
sein? - Warum Benötigen Sie zwei Sätze von Klammern für
$#
? Bearbeiten: Sie ' haben Recht. Es wurde aufwhile (( "$#" ))