Bedeutung von \ vor der Umgebungsvariable

Bedeutung von \ vor der Umgebungsvariable

In ksh auf einer alten Solaris-Box habe ich Folgendes verwendet:

export PS1="$PWD $"

um die Eingabeaufforderung auf das aktuelle Verzeichnis einzustellen. Das funktioniert prima, bis Sie woanders hin wechseln. Dann sehen Sie, dass PWD nicht jedes Mal ausgewertet wird. Mir ist aufgefallen, dass das Problem behoben wird, indem man stattdessen PS1 wie folgt einstellt:

export PS1="\$PWD $"

Ich bin einfach neugierig, wie es heißt, wie es funktioniert, welche anderen Anwendungen es gibt usw. (Es ist eines dieser Dinge, die sich kaum googeln lassen.)

Antwort1

Einige Dokumente sollen dies verdeutlichen.

Von demPOSIX-Standarddokument für die Shell:

Die folgenden Variablen wirken sich auf die Ausführung der Shell aus:
PS1: Jedes Mal, wenn eine interaktive Shell bereit ist, einen Befehl zu lesen, wird der Wert dieser Variable einer Parametererweiterung unterzogen und in den Standardfehler geschrieben.

Einfache Anführungszeichen:
Das Einschließen von Zeichen in einfache Anführungszeichen soll den Literalwert jedes Zeichens innerhalb der einfachen Anführungszeichen beibehalten.

Doppelte Anführungszeichen:
Das Einschließen von Zeichen in doppelte Anführungszeichen soll den Literalwert aller Zeichen innerhalb der doppelten Anführungszeichen beibehalten, mit Ausnahme von
$: Das Dollarzeichen behält seine spezielle Bedeutung bei der Einführung der Parametererweiterung

Escape-Zeichen (Backslash):
Ein Backslash, der nicht in Anführungszeichen gesetzt ist, soll den Literalwert des folgenden Zeichens beibehalten.

Der Wert von PS1unterliegt also der Parametererweiterung, und das ist, was Sie wollen, sodass dies jedes Mal ausgewertet wird, wenn Sie eine Eingabeaufforderung erhalten. Das bedeutet, dass der Wert von eine tatsächliche Zeichenfolge $PWDenthalten muss . Aber,$PWDPS1

PS1="$PWD $ "

wird den Wert vonPWD zum Zeitpunkt der Ausführung der Zuweisungsanweisungin PS1. PS1wird so etwas wie sein /home/poldie $und danach wird es sich nie mehr ändern. Das wollen Sie nicht.

PS1="\$PWD $ "

Der Backslash setzt das in Anführungszeichen $, sodass es PS1die wörtliche Zeichenfolge enthält $PWD $. Das ist Ihr Wunsch.

PS1='$PWD $ '

bewirkt dasselbe. Parameter werden nicht erweitert, wenn sie in einfache Anführungszeichen eingeschlossen sind.

(Hinweis: Ich hatte dies alles ursprünglich als exportAnweisungen, weil der OP sich dafür entschieden hatte, sie als Anweisungen zu schreiben export. @Kusalananda hat sie entfernt. Ich bin mir nicht sicher, warum. Das Exportieren von PS1 ist eine gültige Wahl, wenn Sie möchten, dass untergeordnete Shells (wie die, die durch den :shBefehl in vi erzeugt werden) Ihre benutzerdefinierte Eingabeaufforderung beibehalten.)

Antwort2

Das \Zeichen maskiert das folgende (spezielle) Zeichen. In diesem Fall maskiert es das $, das wir normalerweise verwenden, um eine Variable zu dereferenzieren. Wenn die Shell eine Variablenzuweisung auswertet, expandiert sie zuerst die rechte Seite des Ausdrucks. Ohne das \vorherige $PWDexpandiert die Shell $PWDund weist das Ergebnis zu PS1.

Bei jedoch \behandelt die Shell $PWDes als wörtlichen String und weist es so wie es ist zu PS1, so dass es PS1den String enthält $PWDund nicht den erweiterten Wert der Variable $PWD. Wenn die Shell die Eingabeaufforderung anzeigen will, führt sie erneut eine Variablenerweiterung durch, und dieses Mal, weil $PS1es enthält $PWD,ohne das\, erweitert die Shell es erfolgreich in das aktuelle Verzeichnis.

Derselbe Ansatz kann zum Erstellen dynamischer Variablennamen in Shell-Skripten verwendet werden (das NetBSD- rcNGSystem verwendet dies recht häufig, insbesondere in Skripten zur Steuerung von Netzwerkschnittstellen, wo es aufgrund der Anzahl der Netzwerkadapterbezeichnungen in NetBSD und FreeBSD unpraktisch ist, für jede einzelne Bezeichnung explizit Code zu schreiben).

verwandte Informationen