Was ist der Unterschied zwischen $ path und $ PATH (Kleinbuchstaben gegenüber Großbuchstaben) mit zsh?

12

In FreeBSD 12, das die zshShell verwendet, habe ich diesen Unterschied bemerkt, als ich $path(Kleinbuchstaben) im Vergleich zu $PATH(Großbuchstaben) sah.

echo $path

/ sbin / bin / usr / sbin / usr / bin / usr / lokal / sbin / usr / lokal / bin / usr / home / freebsd / bin

echo $PATH

/ sbin: / bin: / usr / sbin: / usr / bin: / usr / local / sbin: / usr / local / bin: / usr / home / freebsd / bin

Eine Ausgabe wird durch das SPACE-Zeichen, die andere durch das COLON-Zeichen begrenzt.

➥ Woher kommt der Unterschied?

Sind das zwei verschiedene, separate Variablen? Oder löst die Klein- / Großschreibung einen Trick oder eine Bedeutung aus, von der ich nichts weiß?

Ist das ein zshFeature? Oder eine Funktion von FreeBSD?

Basil Bourque
quelle
1
Abgesehen davon: In jeder POSIX-kompatiblen Shell sind Variablennamen mit beliebigen Kleinbuchstaben für die Verwendung durch die Anwendung sicher (um das Verhalten der Shell oder des Systems bei Änderungen nicht unbemerkt zu ändern). Dies ist einer der Punkte, an denen die Entscheidung von zsh, nur dort dem Standard zu folgen, wo es für sie sinnvoll ist, für Skriptautoren Kopfzerbrechen bereiten kann, da die standardisierten Garantien nicht gelten.
Charles Duffy
@CharlesDuffy Haben Sie einen Link zu dem Teil des Standards, in dem etwas über die Variablen in Klein- und Großbuchstaben steht? Vielen Dank.
Mosvy
@mosvy, pubs.opengroup.org/onlinepubs/9699919799/basedefs/… - Bitte beachten Sie, dass Shell- und Umgebungsvariablen einen einzigen Namespace gemeinsam haben. Durch Setzen einer Umgebungsvariablen werden Shell-Variablen initialisiert. Die spezifischen Zeilen: Der Namensraum von Umgebungsvariablennamen, die Kleinbuchstaben enthalten, ist für Anwendungen reserviert. Anwendungen können beliebige Umgebungsvariablen mit Namen aus diesem Namensraum definieren, ohne das Verhalten der Standarddienstprogramme zu ändern.
Charles Duffy
@CharlesDuffy Das gilt hier nicht. Einstellen pathinnen zshwird keine Aktualisierung pathenvvar: path=junk zsh -c 'echo $path; path=garbage; /usr/bin/printenv path'.
Mosvy
@mosvy, du hast mich überzeugt, dass es nicht den Buchstaben des Standards verletzt. Der Geist , auf der anderen Seite, würde for path in "$dir"/*reflexiv sicher-to-Code schreiben.
Charles Duffy

Antworten:

19

Das ist eine Eigenschaft von zshgeerbt von csh/ tcsh.

Die $path Array- Variable ist an die $PATH skalare (String-) Variable gebunden . Jede Änderung an einem spiegelt sich im anderen wider.

In zsh(im Gegensatz zu (t)csh) können Sie weitere Variablen $PATHmit binden typeset -T. Es ist üblich, aber nicht obligatorisch, für den durch Doppelpunkte getrennten Skalar einen Namen in Großbuchstaben und für das Array denselben Namen in Kleinbuchstaben zu verwenden. Während Doppelpunkt das Standardtrennzeichen ist, können andere Trennzeichen verwendet werden (zum Beispiel newline, um eine mehrzeilige Zeichenfolge mit einem Array zu verknüpfen, oder ein Komma, um eine CSV-Zeile mit einem Array zu verknüpfen).

In den letzten Versionen zsh, typeset -p PATHoder typeset -p pathzeigt die Verbindung zwischen den beiden Variablen:

% typeset -p path
typeset -aT PATH path=( /home/chazelas/bin /usr/local/bin /usr/bin /bin )

Dies ist insofern nützlich, als es einfacher ist, entfernte Komponenten hinzuzufügen oder eine Schleife über diese zu erstellen.

Wenn Sie a verwenden typeset -U path, um die Elemente eindeutig zu machen, bleibt die $PATHVariable auch sauber (etwas Ähnliches kann mit erreicht tcshwerden set -f).

Stéphane Chazelas
quelle