Hogyan kezelhetem a kapcsolókat egy shell szkriptben?

Vannak olyan beépített eszközök, amelyek felismerik a -x és a --xxxx kapcsolóként, és nem argumentumként, vagy az összes bemeneti változót végig kell néznie, tesztelnie kell a kötőjeleket, majd elemeznie kell az argumentumokat?

Válasz

getopts használata.

Ez meglehetősen hordozható, mint a POSIX specifikációban. Sajnos nem támogatja a hosszú opciókat.

Lásd még ezt a getopts oktatóanyagot jóvoltából a bash-hackers wiki és ez az kérdés a stackoverflow-ból.

Ha csak rövid lehetőségekre van szükséged, akkor a (nem csendes hibajelentést használ):

# 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 

megjegyzések

  • Meg kell említeni, hogy a getopt -et mindig ellenőrizni kell GNU getopt néven, mielőtt használnád, de nem szabad ' -t használni mivel a getopts egyébként is hordozhatóbb (és általában szebb). Ha van valamilyen okból hívnia kell, hívja GNU-specifikus módon, és győződjön meg arról, hogy a GETOPT_COMPATIBLE nincs a környezetben.
  • Mit csinál a while getopts "ab:" opt kettőspont?
  • @ user394 A : egy opció betű után azt jelöli érvet igényel. A :, mint az első karakter, a hibaüzenetek elnyomását jelenti.

Válasz

Feltételezem, hogy bash-t vagy hasonlót használ. Példa:

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[@]}" "$@" 

Megjegyzések

  • +1 a += tömb használatához. Nem tudtam, hogy ' tudnád, hogy meg tudod csinálni. Szép!

Válasz

A paraméterek elemzéséhez ciklust kell írni. Valójában használhatja a getopts parancs, hogy könnyen megtehesse.

Ez egy egyszerű példa a getopts kézikönyv oldaláról:

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" "$*" 

Válasz

Nemrég írtam egy szkriptet olyan munkához, amely sokoldalú volt, és többféle kapcsolót engedélyezett, bármilyen sorrendben. nyilvánvaló jogi okokból hozza nyilvánosságra a teljes forgatókönyvet (arról nem is beszélve, hogy jelenleg nincs nálam), de itt van ennek a húsa. n egy alprogramot, és hívja a szkript végén:

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 

Azt javaslom, hogy a bash szkriptet korlátozza kevesebb, mint 400 sor / 15 000 karakter; az előbb említett forgatókönyvem ekkora lett, és nagyon nehéz dolgozni rajta. Perlben kezdtem átírni, ami sokkal jobban megfelel a feladatnak. Ezt ne feledje, amikor a szkriptjeivel dolgozik. A Bash kiválóan használható kis szkriptekhez és onelinerekhez, de bármi bonyolultabb, és jobb, ha Perl-be írja.

Megjegyzés: A fentieket még nem tesztelem, így valószínűleg nem működik, de tőle kapja az általános ötletet.

Megjegyzések

  • A options hívásának módja a végén nem helyes, visszaadja -bash: syntax error near unexpected token $@. Hívja options "$@" néven.
  • Igen, összekevertem Perl-t és Bash. Javítva.
  • Ez a while feltétel nem lehet (($#))?
  • Miért két zárójelkészletre lenne szüksége a $# számára?

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük