Was bedeutet: $ {param: = value}?

34

Ich habe Folgendes in einem Benutzerhandbuch für die Z-Shell gelesen :

Ein Synonym für 'wahr' ist ':'; Es wird oft in dieser Form verwendet, um Argumente zu liefern, die Nebenwirkungen haben, aber nicht verwendet werden sollten - so etwas wie

: ${param:=value}

Das ist eine gemeinsame Redewendung in allen Bourne-Shell-Derivaten. In der Parametererweiterung $paramwird der Wert value angegeben, wenn er zuvor leer war, andernfalls allein gelassen. Da dies der einzige Grund für die Parametererweiterung war, :ignorieren Sie das Argument. Tatsächlich erstellt die Shell munter die Befehlszeile - den Doppelpunkt, gefolgt von dem Wert, der unabhängig davon $param, ob die Zuweisung stattgefunden hat oder nicht - und führt dann den Befehl aus. es kommt einfach so vor, dass ':' die Argumente, die ihm vorgebracht wurden, nicht beachtet.

aber ich verstehe es nicht. Ich, dass :Mittel true, aber es gibt zwei Doppelpunkte in dem Ausdruck ein . Warum wird dieses Idiom in allen Bourne-Shell-Derivaten so häufig verwendet? Welchem ​​Zweck dient es?

Anmerkung: Ich bin daran interessiert, was diese Redewendung sowohl in bash als auch in zsh macht .

Vielen Dank

Amelio Vazquez-Reina
quelle
Fragen Sie nach zshoder bash?
Enzotib
@enzotib, beides interessiert mich. Ich habe das klargestellt.
Amelio Vazquez-Reina

Antworten:

31

Lassen Sie uns dies in Stücke zerlegen.

Dieser Code führt den Befehl :mit einigen Argumenten aus. Der Befehl :macht nichts und ignoriert seine Argumente. Daher tut die gesamte Befehlszeile nichts, es sei denn, es treten Nebenwirkungen in den Argumenten auf.

Die Syntax ${parameter_name:=value}ist in allen nicht-antiken Bourne-Shells enthalten, einschließlich ash, bash, ksh und zsh. Bei Bedarf wird der Parameter auf einen Standardwert gesetzt. Es ist äquivalent zu

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

Mit anderen Worten, wenn parameter_namenicht festgelegt oder auf einen leeren Wert festgelegt ist, stellen Sie den angegebenen Wert ein. Führen Sie dann den Befehl mit dem neuen Parameterwert aus. Es gibt eine Variante, ${parameter_name=value}die den Parameter leer lässt, wenn er leer war, und nur dann den angegebenen Wert verwendet, wenn der Parameter nicht gesetzt war.

Sie finden diese Syntax unter „Parametererweiterung“ in der POSIX-Spezifikation sowie in den Handbüchern dash, bash, ksh und zsh.

Es gibt Variationen dieser Syntax, ${parameter_name:-value}die es Ihnen insbesondere ermöglichen , einen Standardwert nur für diese Erweiterung zu verwenden, ohne den Parameter zuzuweisen.

Zusammenfassend : ${parameter_name:=value}ist eine prägnante Schreibweise

if [ -z "$parameter_name" ]; then parameter_name=value; fi
Gilles 'SO - hör auf böse zu sein'
quelle
11

:bedeutet nicht wahr - du denkst wahrscheinlich darüber nach while :, aber selbst in diesem Ausdruck bedeutet es nicht "wahr", es geschieht lediglich, dass es bewertet wird (in der Tat ist es einfach ein Null-Befehl oder noop).

Diese Parametererweiterung ( ${x:=y}) bedeutet " x y zuweisen , wenn x nicht gesetzt oder leer ist, und auf y erweitern ".

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

Die Bash Hacker Wiki hat einen guten Artikel über Parameter Expansion hier .

Der Grund :dafür ist, dass andere Teile des Befehls zwar ausgewertet, aber nicht bearbeitet werden (wie :bei einem Null-Befehl). Sie haben also ${x:=y}die Funktion ausgeführt, ohne etwas anderes zu beeinflussen. Wenn Sie beispielsweise :zu Beginn keine hatten , würde es versuchen, einen Befehl mit dem Namen y auszuführen .

Hier ist bashdie Hilfeseite zu ::

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Chris Down
quelle
3

Der erste :Befehl heißt "noop" oder "no operation". Wie in der Manpage erwähnt, wird es häufig verwendet, um die Argumente zu bewerten.

Der zweite :ist ein Qualifier in der Variablenerweiterung - technisch gesehen :=. Was wie gesagt, dies setzt den Wert, wenn es keinen Wert hat.

Wenn Sie einen Standardwert für eine Umgebungsvariable benötigen, können Sie diese Syntax verwenden. Wenn Sie beispielsweise ein Programm cron(8)ausführen, wird die Umgebung nicht festgelegt und die Punktdateien der Shell werden nicht ausgeführt. Daher müssen Sie möglicherweise einige Standardeinstellungen festlegen.

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

Dann können Sie es 'setzen und vergessen' (bis sich der Standard-JVM ändert).

Arcege
quelle