Co oznacza: $ {param: = wartość}?

34

Przeczytałem następujące w Instrukcji obsługi Z-Shell :

Synonimem „true” jest „:”; jest często używany w tej formie, aby podać argumenty, które mają skutki uboczne, ale których nie należy używać - coś w rodzaju

: ${param:=value}

który jest wspólnym idiomem wszystkich pochodnych powłoki Bourne'a. W rozszerzeniu parametru $paramjest podana wartość wartości, jeśli wcześniej była pusta, a w przeciwnym razie pozostawiona sama. Ponieważ był to jedyny powód rozszerzenia parametru, możesz :zignorować argument. W rzeczywistości powłoka beztrosko buduje wiersz poleceń - dwukropek, a po nim dowolną wartość $param, niezależnie od tego, czy nastąpiło przypisanie, a następnie wykonuje polecenie; tak się składa, że ​​„:” nie przyjmuje podanych argumentów.

ale nie rozumiem tego. Rozumiem :to true, ale w wyrażeniu są dwa dwukropki. Jako drobne pytanie, dlaczego ten idiom jest tak często stosowany we wszystkich pochodnych powłoki Bourne'a? Do czego to służy?

Uwaga: Interesuje mnie to, co robi ten idiom zarówno w bash, jak i w zsh .

Dzięki

Amelio Vazquez-Reina
źródło
Czy prosisz o zshczy bash?
enzotib
@enzotib, interesuje mnie jedno i drugie. Wyjaśniłem to.
Amelio Vazquez-Reina,

Odpowiedzi:

31

Podzielmy to na kawałki.

Ten kod uruchamia polecenie :z kilkoma argumentami. Polecenie :nic nie robi i ignoruje argumenty. Dlatego cała linia poleceń nic nie robi, z wyjątkiem efektów ubocznych występujących w argumentach.

Składnia ${parameter_name:=value}istnieje we wszystkich nie-antycznych powłokach typu Bourne'a, w tym ash, bash, ksh i zsh. W razie potrzeby ustawia parametr na domyślny. Jest to równoważne z

if [ -z "$parameter_name" ]; then parameter_name=value; fi
 ${parameter_name}

Innymi słowy, jeśli parameter_namenie jest ustawione lub jest ustawione na pustą wartość, to ustaw na wskazaną wartość; a następnie uruchom polecenie, używając nowej wartości parametru. Istnieje wariant, ${parameter_name=value}który pozostawia parametr pusty, jeśli był pusty, tylko przy użyciu wskazanej wartości, jeśli parametr był wyłączony.

Znajdziesz tę składnię udokumentowaną w „rozszerzaniu parametrów” w specyfikacji POSIX oraz w instrukcjach dash, bash, ksh i zsh.

Istnieją odmiany tej składni, w szczególności ${parameter_name:-value}umożliwiające użycie wartości domyślnej tylko dla tego rozszerzenia, bez przypisywania do parametru.

Podsumowując, : ${parameter_name:=value}jest to zwięzły sposób pisania

if [ -z "$parameter_name" ]; then parameter_name=value; fi
Gilles „SO- przestań być zły”
źródło
11

:nie oznacza prawdy - prawdopodobnie myślisz o tym while :, ale nawet w tym wyrażeniu nie oznacza to „prawdy”, po prostu zdarza się jej oceniać (w rzeczywistości jest to po prostu polecenie zerowe lub noop).

Ten parametr interpretacji ( ${x:=y}) oznacza „przypisz y do x, jeśli x jest rozbrojony lub pusty, i rozwiń do y ”.

$ echo "${foo:=bar}"
bar
$ foo=baz
$ echo "${foo:=bar}"
baz
$ foo=
$ echo "${foo:=bar}"
bar
$ echo "${foo}"
bar

Wiki Bash Hakerzy ma dobry artykuł na ekspansję parametru tutaj .

Powodem :jest to, że podczas oceny innych części polecenia, nie są one uwzględniane (podobnie jak :polecenie zerowe). W ten sposób ${x:=y}wykonujesz swoją funkcję, nie wpływając na nic innego, na przykład, jeśli nie miałbyś :na początku, próbowałby wykonać polecenie o nazwie y .

Oto bashstrona pomocy na ::

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Chris Down
źródło
3

Pierwsze :to polecenie, nazywa się to „noop” lub „no operation”. Jak powiedziano na stronie podręcznika, jest on często używany do oceny argumentów.

Drugi :jest kwalifikatorem w rozszerzaniu zmiennych - technicznie jest :=. Który, jak powiedziano, ustawia wartość, jeśli nie ma wartości.

Idiomicznie, jeśli potrzebujesz domyślnej wartości zmiennej środowiskowej, możesz użyć tej składni. Na przykład podczas uruchamiania programu cron(8)środowisko nie jest ustawione, a pliki kropki powłoki nie są uruchamiane. Może być konieczne ustawienie niektórych ustawień domyślnych.

: ${JAVA_HOME:=/usr/local/jdk-1.6.0_28}

Następnie możesz „ustawić i zapomnieć” (do czasu zmiany domyślnego jvm).

Arcege
źródło