Ist die Syntax "$ {PS1-}" gültig und wie unterscheidet sie sich von der einfachen Syntax "$ PS1"?

12

Ich schaue mir ein Skript an, das Folgendes enthält:

if [ "${PS1-}" ]; then

Das Nachziehen -stört mich ein bisschen, weil es nicht der Posix- oder Bash-Standardsyntax entspricht. Ist das eine arkane Syntax, die es schon immer gab, oder ein Tippfehler? Verweise auf Normen / Dokumente sind willkommen.

Normalerweise würde ich es codieren:

if [ "$PS1" ]; then

Was ist richtiger oder gibt es einen Unterschied zwischen ihnen?

Gregor
quelle

Antworten:

12

Dies ist definitiv die POSIX-Syntax . Umschreibung:

Verwenden ${parameter-word}, wenn parameterist

  • set und nicht null, dann ersetze den Wert von parameter,
  • set but null, dann setze null und
  • nicht gesetzt, dann ersetzen word.

Beispielsitzung:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

"Null" bedeutet hier einfach die leere Zeichenfolge. In POSIX-Shells gibt es im Gegensatz zu beispielsweise SQL keinen speziellen Nullwert.

Dies ist auch im Abschnitt "Parametererweiterung" von dokumentiert man bash.

l0b0
quelle
1
Ich denke, die Bash- und Dash-Manpages sind unvollständig, weil sie diese Syntax nicht erwähnen (ungerade)!
Gregor
1
@ Gregor In beiden Handbüchern wird dies erwähnt. Im Bash-Handbuch steht es im Absatz vor der Liste der Parametererweiterungen und im Dash-Handbuch im Absatz danach.
Kusalananda
1
OK, "Den Doppelpunkt weglassen ..." Das habe ich nicht gesehen :(
Gregor
zshist die einzige mir bekannte Hülle, die die kolonfreien Varianten explizit erwähnt, anstatt nur zu notieren, was das Weglassen des Doppelpunkts bewirkt.
Chepner
1
@pts, der Text in POSIX verwendet fast ausschließlich den Begriff "null", was möglicherweise die Verwendung in den Manpages erklärt.
ilkkachu
23

Die Variablenerweiterung ${parameter:-word}verwendet den Wert von, $parameterwenn er festgelegt ist, und nicht null (keine leere Zeichenfolge), andernfalls wird die Zeichenfolge verwendet word.

Wenn Sie das weglassen, :wird nicht geprüft, ob der Wert leer ist, sondern nur, ob er nicht gesetzt ist oder nicht.

Dies bedeutet, dass ${PS1-}der Wert auf den Wert von erweitert wird, $PS1wenn er festgelegt ist, und auf einen leeren String, wenn er leer oder nicht festgelegt ist. In diesem Fall ist dies genau das Gleiche, als ${PS1:-}ob der folgende String -ebenfalls leer wäre.

Der Unterschied zwischen "${PS1-}"und "$PS1"ist subtil, wie @Rakesh Sharma feststellt: Beide werden auf den Wert von $PS1oder auf eine leere Zeichenfolge erweitert, wenn sie nicht festgelegt ist. Die Ausnahme ist, wenn set -uaktiv ist. In diesem Fall würde das Erweitern nicht festgelegter Variablen einen Fehler verursachen . Der von festgelegte (leere) Standardwert "${PS1-}"umgeht dies und erweitert einen nicht festgelegten Wert PS1ohne Fehler auf den leeren String.

Dies ist die Standardsyntax ( stammt aus der Bourne-Shell in den späten 70er Jahren ), ebenso wie einige andere, ähnliche Erweiterungen.

Kusalananda
quelle
Und da es zitiert wurde, ist es dasselbe "$PS1", da PS1es leer ist, wenn es leer ist, und die Anführungszeichen verhindern, dass das Wort vollständig verschwindet.
ilkkachu
4
Solange das set -unicht in Kraft ist. Wenn die Option nounset aktiviert ist, gibt "$ PS1" => einen Fehler aus. "$ {PS-}" wird nicht.
@ RakeshSharma das ist ein guter Punkt. Die unterschiedliche Syntax kann in Abhängigkeit von der Option nounset tatsächlich zu unterschiedlichen Ergebnissen führen. Daher ist der Test ["$ {parameter-}"] wahrscheinlich korrekter!
Gregor
1
@ Kusalananda: Bitte beachten Sie, dass ${parameter:-word}der Wert von $parameterNON-NULL verwendet wird. In allen anderen Fällen (dh entweder gesetzt, aber NULL oder nicht gesetzt) ​​wird es verwendet word. Ihr Wortlaut:if its set or null
@ikkachu: Ja das ist richtig. Nur wenn die Variablen set AND nonnull=> sich selbst verwenden. Andernfalls ( set but NULL OR unset) => Wort verwenden.
6

Die Syntax:

${parameter:-word}

und ein spezielles Formular:

${parameter-word}

Ist die gültige Syntax in der POSIX-Shell , bedeutet die Verwendung des Standardwerts, wordwenn parameternicht gesetzt oder null.


Normalerweise ist mit wordleer, dann:

${parameter-}

und:

$parameter

oder:

${parameter}

sind gleichwertig.

Unter der Auswirkung von set -ubewirken jedoch alle nicht gesetzten Variablen, dass die Shell beendet wird. ${parameter-}wird verwendet, um diese strenge Regel zu umgehen. Es funktioniert in beiden Fällen, also ist es korrekter.

cuonglm
quelle