Käyttämällä “ $ {a: -b} ” muuttujien määritykseen komentosarjoissa

Olen tarkastellut muutamia komentosarjoja, jotka muut kirjoittivat (erityisesti Red Hat), ja monet heidän muuttujistaan on määritetty seuraavalla merkinnällä VARIABLE1="${VARIABLE1:-some_val}" tai joillakin laajennetuilla muilla muuttujat VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

Mitä järkeä on käyttää tätä merkintää sen sijaan, että vain ilmoitat arvot suoraan (esim. VARIABLE1=some_val )?

Onko tällä merkinnällä etuja tai mahdollisia virheitä, jotka estetään?

Onko :- erityistä merkitystä tässä yhteydessä ?

Kommentit

  • Katso man bash; etsi lohkoa ” Parametrilaajennus ” (noin 28%). Nämä tehtävät ovat esim. oletustoiminnot: ” Käytä oletusarvoa vain, jos mitään ei ole vielä asetettu. ”
  • Kuten :- asettaa oletusarvon, :+ käytetään arvon muuttamiseen , jos muuttuja on ei tyhjä. Esimerkiksi. v=option; cmd ${v:+ with $v} Suoritetaan ” cmd vaihtoehdolla ”. Mutta jos $ v on nolla, se suorittaa vain ” cmd ”.

Vastaus

Tämä tekniikka antaa muuttujalle arvon, jos toinen muuttuja on joko tyhjä tai sitä ei ole määritelty. HUOMAUTUS: Tämä ”muu muuttuja” voi olla sama tai toinen muuttuja.

ote

${parameter:-word} If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted. 

HUOMAUTUS: Tämä muoto toimii myös, ${parameter-word}. Jos haluat nähdä täydellisen luettelon kaikista Bashissa käytettävissä olevista parametrien laajennuksen muodoista, suosittelen, että tarkastelet tätä aihetta Bash Hacker -wikissä nimeltä ” Parametrilaajennus ”.

Esimerkkejä

muuttujaa ei ole

$ echo "$VAR1" $ VAR1="${VAR1:-default value}" $ echo "$VAR1" default value 

muuttuja olemassa

$ VAR1="has value" $ echo "$VAR1" has value $ VAR1="${VAR1:-default value}" $ echo "$VAR1" has value 

Sama voidaan tehdä arvioimalla muita muuttujia tai suorittamalla komentoja merkinnän oletusarvo-osassa.

$ VAR2="has another value" $ echo "$VAR2" has another value $ echo "$VAR1" $ $ VAR1="${VAR1:-$VAR2}" $ echo "$VAR1" has another value 

Lisää esimerkkejä

Voit myös käyttää hieman erilaista merkintää, jos se on vain VARX=${VARX-<def. value>}.

$ echo "${VAR1-0}" has another value $ echo "${VAR2-0}" has another value $ echo "${VAR3-0}" 0 

Edellä olevassa $VAR1 & $VAR2 määritettiin jo merkkijonolla ”on toinen arvo”, mutta $VAR3 ei määritelty, joten sen sijaan käytettiin oletusarvoa, 0.

Toinen esimerkki

$ VARX="${VAR3-0}" $ echo "$VARX" 0 

Tarkistaminen ja määrittäminen := -merkinnällä

Lopuksi mainitsen kätevän operaattorin, :=. Tämä tarkistaa ja antaa arvon, jos testattava muuttuja on tyhjä tai määrittelemätön.

Esimerkki

Huomaa, että $VAR1 on nyt aseta. Operaattori := teki testin ja tehtävän yhdellä kertaa.

$ unset VAR1 $ echo "$VAR1" $ echo "${VAR1:=default}" default $ echo "$VAR1" default 

Jos arvo on asetettu ennen, sitten se jätetään yksin.

$ VAR1="some value" $ echo "${VAR1:=default}" some value $ echo "$VAR1" some value 

Handy Dandy -viitetaulukko

        taulukon s

viitteet

Kommentit

  • Huomaa, että kaikki nämä eivät ole laajennuksia, jotka on dokumentoitu bash. Q: n ${var:-word} yksi on, mutta ei yllä oleva ${var-word}. POSIX dokumentaatio on kuitenkin mukava taulukko, saattaa olla syytä kopioida se th on vastaus – pubs.opengroup.org/onlinepubs/9699919799/utilities/…
  • @Graeme, se on dokumentoitu, sinun on vain kiinnitettävä huomiota siihen, että kaksoispisteen jättäminen johtaa testiin vain parametrille, jota ei ole asetettu.
  • echo "${FOO:=default}" on hieno, jos todella haluat echo. Mutta jos et ’ t, kokeile sisäänrakennettua :: ${FOO:=default} $FOO -asetuksesi on default kuten yllä (ts. Jos sitä ei vielä ole määritetty). Mutta ’ ei sisällä prosessin $FOO kaikuja.
  • Ok, löysi vastauksen: pinonkulku.fi / q / 24405606/1172302 . ${4:-$VAR} -toiminnon käyttö toimii.
  • +1 vain yksityiskohtaisen vastauksen saamiseksi. Mutta myös siitä, että viittaat erinomaiseen bash-wikiin. Ja myös siitä, että annat esimerkkejä ja taulukon. Helvetti, vain + 1: t kokonaan alas 🙂 Minulla oli melkein syntaksi oikein, mutta ei aivan – en vain ’ välittänyt tarpeeksi etsimään man-sivulta (ei vaikeaa mutta en voinut ’ muistaa minkä otsikon alla se oli, ja olen ’ ollut hereillä 4 aamusta lähtien :() ..

vastaus

@slm on jo sisällyttänyt POSIX-asiakirjat – jotka ovat erittäin hyödyllisiä – mutta ne eivät todellakaan laajenna sitä, miten nämä parametrit voidaan yhdistää vaikuttamaan toisiinsa. Tätä lomaketta ei vielä mainita:

${var?if unset parent shell dies and this message is output to stderr} 

Tämä on ote toisesta vastauksestani , ja mielestäni se osoittaa hyvin näiden toimien:

 sh <<-\CMD _input_fn() { set -- "$@" #redundant echo ${*?WHERES MY DATA?} #echo is not necessary though shift #sure hope we have more than $1 parameter : ${*?WHERES MY DATA?} #: do nothing, gracefully } _input_fn heres some stuff _input_fn one #here # shell dies - third try doesnt run _input_fn you there? # END CMD heres some stuff one sh: line :5 *: WHERES MY DATA? 

Toinen esimerkki samalta :

 sh <<-\CMD N= #N is NULL _test=$N #_test is also NULL and v="something you would rather do without" ( #this subshell dies echo "v is ${v+set}: and its value is ${v:+not NULL}" echo "So this ${_test:-"\$_test:="} will equal ${_test:="$v"}" ${_test:+${N:?so you test for it with a little nesting}} echo "sure wish we could do some other things" ) ( #this subshell does some other things unset v #to ensure it is definitely unset echo "But here v is ${v-unset}: ${v:+you certainly wont see this}" echo "So this ${_test:-"\$_test:="} will equal NULL ${_test:="$v"}" ${_test:+${N:?is never substituted}} echo "so now we can do some other things" ) #and even though we set _test and unset v in the subshell echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}" # END CMD v is set: and its value is not NULL So this $_test:= will equal something you would rather do without sh: line 7: N: so you test for it with a little nesting But here v is unset: So this $_test:= will equal NULL so now we can do some other things _test is still NULL and v is still something you would rather do without 

Yllä olevassa esimerkissä hyödynnetään kaikkia 4 POSIX-parametrikorvauksen muotoa ja niiden erilaiset :colon null tai not null testit. Yllä olevassa linkissä on lisätietoja, ja tässä se on taas .

Toinen asia, jota ihmiset usein eivät ota huomioon ${parameter:+expansion} on, kuinka hyödyllinen se voi olla täällä-asiakirjassa. Tässä on toinen ote erilainen vastaus :

TOP

Tässä asetat joitain oletusasetuksia ja valmistaudut tulostamaan ne, kun niitä kutsutaan …

#!/bin/sh _top_of_script_pr() ( IFS="$nl" ; set -f #only split at newlines and don"t expand paths printf %s\\n ${strings} ) 3<<-TEMPLATES ${nl= } ${PLACE:="your mother"s house"} ${EVENT:="the unspeakable."} ${ACTION:="heroin"} ${RESULT:="succeed."} ${strings:=" I went to ${PLACE} and saw ${EVENT} If you do ${ACTION} you will ${RESULT} "} #END TEMPLATES 

KESKI

Tässä määritetään muut toiminnot, joiden avulla tulostustoiminto voidaan kutsua niiden tulosten perusteella …

 EVENT="Disney on Ice." _more_important_function() { #...some logic... [ $((1+one)) -ne 2 ] && ACTION="remedial mathematics" _top_of_script_pr } _less_important_function() { #...more logic... one=2 : "${ACTION:="calligraphy"}" _top_of_script_pr } 

BOTTOM

Sinulla on nyt kaikki asetukset, joten tässä suoritat ja vedät tulokset.

 _less_important_function : "${PLACE:="the cemetery"}" _more_important_function : "${RESULT:="regret it."}" _less_important_function 

TULOKSET

Tulen selvittämään miksi hetkessä, mutta yllä olevan suorittaminen tuottaa seuraavat tulokset:

_less_important_function()"s ensimmäinen ajo:

Kävin äitisi talossa ja näin Disney on Ice.

Jos teet kalligrafiaa , onnistut.

th fi _more_important_function():

Kävin hautausmaalla ja näki Disneyn jäällä.

Jos suoritat korjaavaa matematiikkaa , onnistut.

_less_important_function() uudelleen:

Kävin hautausmaalla ja näin Disneyn jäällä.

Jos harjoittelet korjaavaa matematiikkaa, katu sitä.

Kuinka se toimii:

Tärkein piirre tässä on käsite conditional ${parameter} expansion. Voit asettaa muuttujan arvoksi arvo vain, jos se on asetettu tai tyhjä käyttämällä muotoa:

${var_name : = desired_value}

Jos haluat sen sijaan asettaa vain muuttamattoman muuttujan, jätät ja nolla-arvot pysyvät ennallaan.

SOVELTAMISALA:

Saatat huomata, että yllä olevassa esimerkissä $PLACE ja $RESULT muutetaan, kun ne asetetaan parameter expansion vaikka _top_of_script_pr() on jo kutsuttu, asettamalla ne oletettavasti sen ollessa käynnissä. Syynä tähän on se, että _top_of_script_pr() on ( subshelled ) toiminto – olen mukana se parens , eikä muille käytetty { curly braces } . Koska sitä kutsutaan alikuoressa, jokainen sen asettama muuttuja on locally scoped ja palatessaan vanhempaan kuoreen nämä arvot katoavat.

Mutta kun _more_important_function() asettaa $ACTION , se on globally scoped joten se vaikuttaa _less_important_function()"s toiseen arviointiin: $ACTION koska _less_important_function() asettaa $ACTION vain ${parameter:=expansion}.

Kommentit

  • Hyvä nähdä, että lyhenteen oletusarvo toimii Bourne Shellissä

Vastaa

Henkilökohtainen kokemus.

Käytän tätä muotoa joskus skripteissäni tapauskohtaisesti ylittämällä arvoja, esim.jos minulla on:

$ cat script.sh SOMETHING="${SOMETHING:-something}"; echo "$SOMETHING"; 

Voin suorittaa:

$ env SOMETHING="something other than the default value" ./script.sh` 

tarvitsematta muuttaa alkuperäisen oletusarvon SOMETHING.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *