Onko olemassa joitain sisäänrakennettuja työkaluja, jotka tunnistavat -x
ja --xxxx
kytkiminä, ei argumentteina, vai onko sinun mentävä läpi kaikki syötemuuttujat, testattava viivoja ja sitten jäsennettävä argumentit sen jälkeen?
Vastaa
Käytä getopts
.
Se on melko kannettava sellaisena kuin se on POSIX-määrityksessä. Valitettavasti se ei tue pitkiä vaihtoehtoja.
Katso myös tämä getopts
opetusohjelma bash-hakkereiden wiki ja tämä kysymys pinoverflowsta.
Jos tarvitset vain lyhyitä vaihtoehtoja, tyypillinen käyttötapa mallille getopts
(käyttää hiljaista virheraportointia) on:
# 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
kommentit
- On syytä mainita, että
getopt
tulee aina varmistaa GNU getopt -toiminnoksi ennen käyttöä, mutta sinun ei pitäisi ' käyttää sitä silti koskagetopts
on joka tapauksessa kannettavampi (ja yleensä mukavampi). Jos sinun täytyy jostain syystä kutsua sitä, soita sille GNU-erityisellä tavalla, ja varmista, ettäGETOPT_COMPATIBLE
ei ole ympäristössä. - Mitä
while getopts "ab:" opt
-kohdan kaksoispiste tekee? - @ user394
:
optiokirjan jälkeen merkitsee sitä vaatii argumentin.:
ensimmäisenä merkkinä tarkoittaa virhesanomien estämistä.
Vastaa
Oletan, että käytät bashia tai vastaavaa. Esimerkki:
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[@]}" "$@"
kommentit
Vastaa
Parametrien jäsentämiseksi sinun on kirjoitettava sykli. Voit käyttää getopts
-komento tehdä se helposti.
Tämä on yksinkertainen esimerkki getopts
-sivulta:
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" "$*"
vastaus
Kirjoitin hiljattain käsikirjoituksen työstä, joka oli monipuolinen ja sallittu monenlaisille kytkimille missä tahansa järjestyksessä. En voi ”t paljastaa koko käsikirjoitus ilmeisistä oikeudellisista syistä (puhumattakaan siitä, että minulla ei ole sitä tällä hetkellä), mutta tässä on sen liha .. voit laittaa sen i n aliohjelma ja kutsu sitä komentosarjan loppuun:
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
Suosittelen, että rajoitat bash-komentosarjan alle 400 riviin / 15 kt merkkiin; edellä mainittu käsikirjoitukseni kasvoi tämän koon ohi ja sen työstäminen oli erittäin vaikeaa. Aloin kirjoittaa sen uudelleen Perliin, joka sopii paljon paremmin tehtävään. Pidä tämä mielessä, kun käsittelet skriptejäsi bashissa. Bash on hieno pienille skripteille ja onelinereille, mutta kaikki monimutkaisempi ja sinun on parempi kirjoittaa se Perliin.
Huomaa, en ole testannut yllä mainittua, joten se ei todennäköisesti toimi, mutta saat siitä yleisen idean.
Kommentit
- Tapa, jolla kutsut
options
lopussa ei ole oikein, se palauttaa-bash: syntax error near unexpected token $@
. Kutsu sitä nimelläoptions "$@"
. - Kyllä, sekoitin Perlin ja Bash. Korjattu.
- Että
while
-ehtoa ei pitäisi sen sijaan olla(($#))
? - Miksi tarvitsetko kaksi sulkeja ryhmälle
$#
? Muokkaa: olet ' oikeassa. Korjattu se arvoonwhile (( "$#" ))
+=
-taulukkoa. En tiennyt ' tien, että voit tehdä sen. Hienoa!