Bruker “ $ {a: -b} ” for variabel tildeling i skript

Jeg har sett på noen få skript andre mennesker skrev (spesielt Red Hat), og mange av variablene deres tildeles ved hjelp av følgende notasjon VARIABLE1="${VARIABLE1:-some_val}" eller noen utvider andre variabler VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

Hva er vitsen med å bruke denne notasjonen i stedet for bare å erklære verdiene direkte (f.eks. VARIABLE1=some_val )?

Er det fordeler med denne notasjonen eller mulige feil som kan forhindres?

Har :- spesifikk betydning i denne sammenhengen ?

Kommentarer

  • Ta en titt på man bash; søk etter blokken » Parameterutvidelse » (omtrent 28%). Disse oppgavene er f.eks. standardfunksjoner: » Bruk standardverdien bare hvis ingen er satt ennå. »
  • Som :- angir standardverdi, :+ brukes til å endre verdi hvis variabelen er ikke null. F.eks. v=option; cmd ${v:+ with $v} Kjører » cmd med alternativ «. Men hvis $ v er null, vil den bare kjøre » cmd «.

Svar

Denne teknikken gjør det mulig for en variabel å få tildelt en verdi hvis en annen variabel enten er tom eller udefinert. MERK: Denne «andre variabelen» kan være den samme eller en annen variabel.

utdrag

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

MERK: Dette form fungerer også, ${parameter-word}. Hvis du «vil se en fullstendig liste over alle former for parameterutvidelser som er tilgjengelige i Bash, foreslår jeg sterkt at du tar en titt på dette emnet i Bash Hacker» -wiki med tittelen: « Parameterutvidelse «.

Eksempler

variabelen finnes ikke

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

variabel eksisterer

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

Det samme kan gjøres ved å evaluere andre variabler, eller kjøre kommandoer innenfor standardverdidelen av notasjonen.

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

Flere eksempler

Du kan også bruke en litt annen notasjon der den bare er VARX=${VARX-<def. value>}.

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

I ovenstående $VAR1 & $VAR2 var allerede definert med strengen «har en annen verdi» men $VAR3 var udefinert, så standardverdien ble brukt i stedet, 0.

Et annet eksempel

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

Kontroll og tildeling ved hjelp av := notasjon

Til slutt vil jeg nevne den praktiske operatøren, :=. Dette vil gjøre en sjekk og tildele en verdi hvis variabelen som testes er tom eller udefinert.

Eksempel

Legg merke til at $VAR1 er nå sett. Operatøren := gjorde testen og tildelingen i en enkelt operasjon.

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

Men hvis verdien er satt tidligere, så er det igjen.

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

Handy Dandy Reference Table

        ss av tabellen

Referanser

Kommentarer

  • Merk at ikke alle disse er utvidelser er dokumentert i bash. ${var:-word} en i Q er, men ikke ${var-word} over. POSIX Dokumentasjonen har et fint bord skjønt, kan være verdt å kopiere den til th er svar – pubs.opengroup.org/onlinepubs/9699919799/utilities/…
  • @Graeme, det er dokumentert, du trenger bare å være oppmerksom på Utelatelse av tykktarmen resulterer i en test bare for en parameter som ikke er satt.
  • Bruk av echo "${FOO:=default}" er flott hvis du faktisk vil ha echo. Men hvis du ikke ‘ t, så prøv : innebygd … : ${FOO:=default} Din $FOO er satt til default som ovenfor (dvs. hvis den ikke allerede er angitt). Men det er ‘ ingen ekko av $FOO i prosessen.
  • Ok, fant et svar: stackoverflow.com / q / 24405606/1172302 . Å bruke ${4:-$VAR} vil fungere.
  • +1 bare for det detaljerte svaret. Men også for det faktum at du refererer til den utmerkede bash wiki. Og også for det faktum at du gir eksempler og en tabell. Helvete, bare +1 hele veien ned 🙂 Når det gjelder meg hadde jeg nesten syntaksen riktig, men ikke helt – jeg brydde meg bare ikke ‘ til å søke på mannssiden (ikke vanskelig men jeg kunne ikke ‘ ikke huske hvilken overskrift det var under, og jeg ‘ har vært våken siden 4 i morges :() ..

Svar

@slm har allerede tatt med POSIX-dokumenter – som er veldig hjelpsomme – men de utvider egentlig ikke hvordan disse parametrene kan kombineres for å påvirke hverandre. Det er foreløpig ingen omtale her av dette skjemaet:

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

Dette er et utdrag fra et annet svar av meg, og jeg synes det demonstrerer veldig godt hvordan disse fungerer:

 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? 

Et annet eksempel fra samme :

 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 

Eksemplet ovenfor utnytter alle 4 former for POSIX-parametererstatning og deres forskjellige :colon null eller not null tester. Det er mer informasjon i lenken over, og her er det igjen .

En annen ting som folk ofte ikke vurderer om ${parameter:+expansion} er hvor veldig nyttig det kan være i et her-dokument. Her er et annet utdrag fra en annet svar :

TOP

Her vil du angi noen standardinnstillinger og forberede deg til å skrive dem ut når du blir ringt …

#!/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 

MIDDEL

Dette er hvor du definerer andre funksjoner som skal kalles utskriftsfunksjonen din basert på resultatene …

 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 } 

BUNN

Du har alt oppsett nå, så her er det du skal utføre og trekke resultatene dine.

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

RESULTATER

Jeg vil se nærmere på hvorfor et øyeblikk, men å kjøre ovenstående gir følgende resultater:

_less_important_function()"s første løp:

Jeg gikk hjem til moren din og så Disney on Ice.

Hvis du gjør kalligrafi vil du lykkes.

th no _more_important_function():

Jeg dro til kirkegården og så Disney on Ice.

Hvis du gjør avhjelpende matematikk vil du lykkes.

_less_important_function() igjen:

Jeg dro til kirkegården og så Disney on Ice.

Hvis du gjør avhjelpende matematikk, vil du angre på det.

HVORDAN DET FUNGERER:

Nøkkelfunksjonen her er begrepet conditional ${parameter} expansion. Du kan sette en variabel til en verdi bare hvis den ikke er satt eller null ved hjelp av skjemaet:

${var_name : = desired_value}

Hvis du i stedet bare vil angi en usett variabel, vil du utelate og nullverdier vil forbli som de er.

PÅ OMFANG:

Du vil kanskje legge merke til at i eksemplet ovenfor $PLACE og $RESULT blir endret når de er angitt via parameter expansion selv om _top_of_script_pr() allerede er kalt, antagelig innstiller du dem når den kjøres. Grunnen til at dette fungerer er at _top_of_script_pr() er en ( subshelled ) funksjon – jeg vedlagt det i parens i stedet for { curly braces } som brukes til de andre. Fordi den kalles i et subshell, er hver variabel den angir locally scoped og når den går tilbake til sitt overordnede skall, forsvinner disse verdiene.

Men når _more_important_function() setter $ACTION er det globally scoped så det påvirker _less_important_function()"s andre evaluering av $ACTION fordi _less_important_function() setter $ACTION bare via ${parameter:=expansion}.

Kommentarer

  • Godt å se at standardverdien for stenografi fungerer i Bourne Shell

Svar

Personlig opplevelse.

Jeg bruker dette formatet noen ganger i skriptene mine for å gjøre ad-hoc-overkjøring av verdier, f.eks.hvis jeg har:

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

kan jeg løpe:

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

uten å måtte endre den opprinnelige standardverdien SOMETHING.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *