Použití “ $ {a: -b} ” pro přiřazení proměnných ve skriptech

Díval jsem se na několik skriptů, které napsali jiní lidé (konkrétně Red Hat), a mnoho jejich proměnných je přiřazeno pomocí následujícího zápisu VARIABLE1="${VARIABLE1:-some_val}" nebo nějakého dalšího proměnné VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

Jaký má smysl používat tento zápis namísto přímého deklarace hodnot (např. VARIABLE1=some_val )?

Existují výhody tohoto zápisu nebo možné chyby, kterým by se dalo zabránit?

:- v tomto kontextu konkrétní význam? ?

Komentáře

  • Podívejte se na man bash; vyhledejte blok “ Rozšíření parametrů “ (přibližně 28%). Těmito úkoly jsou např. výchozí funkce: “ Výchozí hodnotu použijte pouze v případě, že ještě nebyla nastavena žádná. “
  • Jako :- nastavuje výchozí hodnotu, :+ se používá k změně hodnoty , pokud je proměnná nenulový. Např. v=option; cmd ${v:+ with $v} Spustí “ cmd s možností „. Pokud je však $ v null, spustilo by se to pouze “ cmd „.

Odpověď

Tato technika umožňuje přiřadit proměnné hodnotu, pokud je jiná proměnná prázdná nebo není definována. POZNÁMKA: Tato „jiná proměnná“ může být stejná nebo jiná proměnná.

výňatek

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

POZNÁMKA: Toto formulář také funguje, ${parameter-word}. Pokud byste chtěli vidět úplný seznam všech forem rozšíření parametrů dostupných v Bash, pak vám velmi doporučuji podívat se na toto téma ve wiki Bash Hacker s názvem: „ Rozšíření parametrů „.

Příklady

proměnná neexistuje

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

proměnná existuje

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

Totéž lze provést vyhodnocením jiných proměnných nebo spuštěním příkazů v části výchozí hodnoty notace.

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

Další příklady

Můžete také použít mírně odlišnou notaci, pokud jde pouze o VARX=${VARX-<def. value>}.

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

Ve výše uvedeném $VAR1 & $VAR2 již byly definovány pomocí řetězce „has another value“, ale $VAR3 bylo nedefinováno, takže místo toho byla použita výchozí hodnota, 0.

Další příklad

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

Kontrola a přiřazování pomocí := notace

Nakonec zmíním praktického operátora, :=. To provede kontrolu a přiřadí hodnotu, pokud je testovaná proměnná prázdná nebo nedefinovaná.

Příklad

Všimněte si, že $VAR1 je nyní soubor. Operátor := provedl test a přiřazení v jediné operaci.

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

Je-li však nastavena hodnota předtím, pak už zůstane sám.

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

Handy Dandy Reference Table

        ss tabulky

Reference

Komentáře

  • Všimněte si, že ne všechna rozšíření jsou popsána v bash. ${var:-word} v Q je, ale ne ${var-word} výše. POSIX dokumentace má pěknou tabulku, možná by stálo za to ji zkopírovat do th je odpověď – pubs.opengroup.org/onlinepubs/9699919799/utilities/…
  • @Graeme, je to zdokumentováno, stačí věnovat pozornost Vynechání dvojtečky vede k testu pouze pro parametr, který není nastaven.
  • Použití echo "${FOO:=default}" je skvělý, pokud skutečně chcete echo. Pokud ale ‚ t nevyzkoušíte, zkuste : integrovaný … : ${FOO:=default} Váš $FOO je nastaven na default, jak je uvedeno výše (tj. Pokud již není nastaven). Ale ‚ v procesu nedochází k ozvěně $FOO.
  • Dobře, našel jsem odpověď: stackoverflow.com / q / 24405606/1172302 . Použití ${4:-$VAR} bude fungovat.
  • +1 pouze pro podrobnou odpověď. Ale také za to, že odkazujete na vynikající bash wiki. A také za to, že uvedete příklady a tabulku. Sakra, jen + 1s úplně dolů 🙂 Co se mě týče, syntaxi jsem téměř měl správně, ale ne tak docela – prostě jsem se ‚ nestaral natolik, abych prohledal manuálovou stránku (není to těžké ale nemohl jsem si ‚ vzpomenout, pod jakým nadpisem to bylo, a ‚ jsem byl vzhůru od 4 ráno :() ..

Odpověď

@slm již zahrnoval POSIX dokumenty – které jsou velmi užitečné – ale ve skutečnosti nerozšíří, jak lze tyto parametry kombinovat tak, aby se vzájemně ovlivňovaly. O tomto formuláři zde zatím není žádná zmínka:

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

Toto je výňatek z další mé odpovědi a myslím, že velmi dobře ukazuje, jak fungují:

 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? 

Další příklad z stejného :

 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 

Výše uvedený příklad využívá výhod všech 4 forem substituce parametrů POSIX a jejich různé :colon null nebo not null testy. Ve výše uvedeném odkazu je více informací a je to znovu .

Další věc, o které lidé často neuvažují ${parameter:+expansion}, je, jak velmi užitečná může být v dokumentu zde. Zde je další výňatek z jiná odpověď :

NEJLEPŠÍ

Zde nastavíte některá výchozí nastavení a připravíte se na jejich tisk při volání …

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

STŘEDNÍ

Zde definujete další funkce pro volání vaší tiskové funkce na základě jejich výsledků …

 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

Nyní máte vše nastaveno, takže zde můžete provádět a stahovat výsledky.

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

VÝSLEDKY

Ve chvíli se podívám na důvod, ale spuštění výše uvedeného způsobí následující výsledky:

_less_important_function()"s první spuštění:

Šel jsem do domu vaší matky a viděl jsem Disney on Ice.

Pokud uděláte kaligrafii , uspějete.

th en _more_important_function():

Šel jsem na hřbitov a viděl Disney on Ice.

Pokud uděláte opravnou matematiku , uspějete.

_less_important_function() znovu:

Šel jsem na hřbitov a viděl jsem Disney on Ice.

Pokud se budete věnovat opravné matematice, budete litovat.

JAK TO FUNGUJE:

Klíčovou funkcí je zde koncept conditional ${parameter} expansion. Můžete nastavit proměnnou na hodnota pouze v případě, že je deaktivována nebo nulová pomocí formuláře:

${var_name : = desired_value}

Pokud si přejete nastavit pouze nenastavenou proměnnou, vynechali byste a nulové hodnoty by zůstaly tak, jak jsou.

NA OBLAST PŮSOBNOSTI:

Můžete si všimnout, že ve výše uvedeném příkladu $PLACE a $RESULT se změní, když je nastaveno pomocí parameter expansion i když _top_of_script_pr() již byl volán, pravděpodobně je nastaví, když je spuštěn. Důvod, proč to funguje, je ten, že _top_of_script_pr() je ( subshelled ) funkce – přikládám je v parens spíše než v { curly braces } použitém pro ostatní. Protože se volá v subshellu, každá proměnná, kterou nastaví, je locally scoped a při návratu do nadřazeného shellu tyto hodnoty zmizí.

Ale když _more_important_function() nastaví $ACTION je to globally scoped takže ovlivňuje _less_important_function()"s druhé hodnocení $ACTION protože _less_important_function() nastavuje $ACTION pouze prostřednictvím ${parameter:=expansion}.

Komentáře

  • Je dobré vidět, že zkratková výchozí hodnota funguje v Bourne Shell

Odpověď

Osobní zkušenost.

Tento formát někdy používám ve svých skriptech k ad-hoc překročení hodnot, např.pokud mám:

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

mohu spustit:

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

bez nutnosti změny původní výchozí hodnota SOMETHING.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *