[!NOTE] Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.

Zsh-Startdateien: ~/.zprofile gegenüber ~/.zshrc auf macOS und Linux

Wenn Ihre Terminalumgebung langsam wirkt oder eine Umgebungsvariable in einem Terminal sichtbar ist, aber in einem anderen nicht, liegt die Ursache oft im Startmodus von Zsh. Die beiden Dateien, auf die die meisten Nutzer zuerst zurückgreifen, sind ~/.zprofile und ~/.zshrcAber auch der Dateinamen allein gibt nicht an, ob eine Zeile dorthin gehört.

Zsh wählt die Startdateien anhand zweier unabhängiger Kriterien aus: ob es sich um eine Login-Shell handelt und ob sie interaktiv ist. Terminalanwendungen unter macOS und Linux können unterschiedliche Kombinationen verwenden, weshalb Sie die laufende Shell überprüfen sollten, anstatt davon auszugehen, dass das Betriebssystem dies für Sie entscheidet.

Zusammenfassung. Führen Sie die Initialisierung des Anmeldungs-Session-Prozesses durch. .zprofile sowie interaktives Verhalten in .zshrc. Beibehalten. .zshenv stumm und minimal. Bewegen Sie die Hook‑Funktionen des interaktiven Versionsverwalters nicht in .zprofile oder das gesamte Profil aus einer Quelle abrufen .zshrc; Überprüfen Sie den von der Tool generierten Code und befolgen Sie die aktuellen Anweisungen in Zsh.

Zsh bewertet zwei unabhängige Flags

Zsh-Startdateien, die je nach Login- und Interaktionsmodus ausgewählt werden

Eine Shell kann sein:

Terminalanwendungen, IDEs, entfernte Sessions-Umgebungen, Multiplexer sowie explizite Shell-Flags können unterschiedliche Modi wählen. Allein das Betriebssystem bestimmt hier nicht das Ergebnis.

Fragen Sie den laufenden Shell anstelle von Vermutungen:

print -r -- "interactive=$options[interactive] login=$options[login]"

Die tatsächliche Startreihenfolge

Zsh liest zunächst die globalen Dateien und anschließend die entsprechenden Benutzerdateien. Bei der Standardkonfiguration RCS Unter den Optionen ist die Reihenfolge der Benutzerdateien wie folgt:

  1. $ZDOTDIR/.zshenv für jede Aufrufung von Zsh $ZDOTDIR/.zprofile Wenn es sich um eine Login-Shell handelt
  2. $ZDOTDIR/.zshrc Wenn die Shell interaktiv ist
  3. $ZDOTDIR/.zlogin Wenn es sich um eine Login-Shell handelt $ZDOTDIR/.zlogout wenn eine Anmelde-SHELL normal beendet wird

Wenn ZDOTDIR ist nicht gesetzt, Zsh verwendet $HOME. Die systemweiten Dateipfade sind installationsbezogen; die üblichen Standardwerte lauten /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin, und /etc/zlogout.

Zsh-Startablauf für vier Shell-Modi

Die Anweisung stellt lediglich ein Filter dar und garantiert keine Lebenszyklusunterstützung. .zprofile Es wird einmal pro Login-Shell-Prozess ausgeführt, und nicht einmal pro Computer-Login. Da jede neue Terminalleiste eine Login-Shell startet, wird der Inhalt von jeder Leiste gelesen.

Was gehört in jede Datei

DateiAuswahlregelGute KandidatenVermeiden Sie
.zshenvJeder ZshSeltene Variablen, die von jedem Zsh-Prozess benötigt werdenAusgabe, Aliase, Prompts, Netzwerkaufrufe, langsame Befehle
.zprofileAnmelde-ShellsEinrichtung des Anmeldepfades für Session sowie Exportierung der Standardwerteinteraktive Hooks, Autocompletion-Funktionen sowie Tastenkombinationen
.zshrcInteraktive ShellsPrompt, Autocomplete-Funktionen, Alias-Einstellungen, Shell-Optionen sowie Hooks für interaktive ToolsAusgaben oder Mutationen, die für Skripte bestimmt sind
.zloginLogin-Shells, nachdem .zshrcseltene Login-Aktionen nach der InteraktionKonfiguration, die vorausgehen muss .zshrc
.zlogoutBeendigung der Login-Shellkleine Reinigungs- oder Terminal-Reset-AktionenWichtig zu beachten: Der Zustand muss auch nach einem Absturz erhalten bleiben. exec

Beibehalten .zshenv langweilig

Jeder nicht-interaktive zsh -c liest ein .zshenv. Ein echoEin Aufruf des Package-Managers oder ein aufwändiger Unterprozess kann die Ausgabe von Befehlen verfälschen und Skripte verlangsamen. Die meisten Benutzer benötigen in dieser Datei entweder kaum etwas oder gar nichts.

eine exportierte Variable in .zprofile Es wird von den Kindprozessen dieser Login-Shell vererbt. Es wird nicht automatisch in unverwandte GUI-Anwendungen, Dienste oder Shells injiziert, deren Elterprozess das Datei niemals gelesen hat.

Verwendung .zprofile für eine Einrichtung nur zum Anmelden

Ein kleines Profil kann exportierte Standardwerte sowie einen idempotenten Ablauf festlegen:

# ~/.zprofile
export EDITOR=nvim
export VISUAL=nvim

# Zsh ties the path array to the PATH scalar.
typeset -U path PATH
path=("$HOME/.local/bin" $path)
export PATH

typeset -U Es entfernt doppelte Einträge aus dem Array. Dadurch wird das wiederholte Abrufen sicherer, wobei Startdateien dennoch unnötige Aufwände vermeiden sollten.

Verwendung .zshrc für den interaktiven Zustand

# ~/.zshrc
setopt auto_cd hist_ignore_all_dups share_history

autoload -Uz compinit
compinit

alias ll='ls -lah'
bindkey -e

Aliasse, Autocomplete-Widgets, Tastenkarten, Prompts sowie Hook-Funktionen für Verzeichniswechsel gehören zur interaktiven Shell, die sie verwendet.

Versionsverwaltungstools überschreiten die Grenzen einfacher Dateien

„Setzen Sie Versionierungsmanager ein.“ .zprofile „Weil sie langsam sind“ ist ein unzuverlässiger Ratschlag. Ein Versionstool kann verschiedene Arten von Code erzeugen:

Die interaktiven Komponenten müssen in jeder interaktiven Shell vorhanden sein, einschließlich einer verschachtelten zsh aus einem Editor gestartet. Aktuell fnm Die Dokumentation weist daher diesen Hook auf. .zshrc:

eval "$(fnm env --use-on-cd --shell zsh)"

Die aktuelle Dokumentation zu pyenv legt ebenso die vollständige interaktive Initialisierung fest .zshrc:

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && path=("$PYENV_ROOT/bin" $path)
eval "$(pyenv init - zsh)"

Pyenv dokumentiert ein engeres pyenv init --path Modus für die Einrichtung des Shim-Pfades, jedoch vollständig pyenv init Es werden außerdem Funktionen zur Autocompletion sowie Shell-Funktionen installiert. Überprüfen Sie vor dem Aufteilen die aktuelle Dokumentation sowie die erzeugten Ausgaben eines Tools.

Falls der Startzeitraum langsam ist, messen Sie diesen vor dem Übersetzen des Codes in einen Modus, in dem er nicht mehr funktioniert.

Beziehen Sie nicht den gesamten Profilinhalt aus einer externen Quelle. .zshrc

Eine gängige plattformübergreifende Workaround-Lösung ist:

# Avoid this blanket coupling.
source ~/.zprofile

Dadurch werden Aktionen, die ursprünglich nur zum Anmelden bestimmt waren, zu Aktionen pro interaktiverem Shell-Session, wodurch Prozesse wie der Neustart von Agent, der Zugriff auf das Schlüsselbund, die Ausgabe oder Änderungen von Pfaden wiederholt werden können.

Falls sowohl interaktive Shells für eingeloggte als auch für nicht eingeloggte Benutzer eine kleine Anzahl statischer Exporte benötigen, extrahieren Sie einen idempotenten Fragment und rufen Sie dieses gezielt auf:

# ~/.config/zsh/environment.zsh
typeset -U path PATH
path=("$HOME/.local/bin" $path)
export PATH EDITOR=nvim VISUAL=nvim
# ~/.zprofile
source "$HOME/.config/zsh/environment.zsh"
# ~/.zshrc
if [[ ! -o login ]]; then
  source "$HOME/.config/zsh/environment.zsh"
fi

# Interactive-only configuration follows.

Dieses Muster sorgt dafür, dass gemeinsam genutzte Daten von den Auswirkungen des Anmeldevorgangs getrennt bleiben. Eine weitere valide Option besteht darin, den Terminal oder den Session-Manager konsequent auf denselben Modus einzustellen, anstatt beide Modi zu unterstützen.

Diagnose die Shell, die langsam ist oder keinen Zustand besitzt

Reproduzieren Sie jeden Modus direkt:

zsh -lic 'print "login interactive"'
zsh -ic  'print "non-login interactive"'
zsh -lc  'print "login non-interactive"'
zsh -c   'print "non-login non-interactive"'

Erheben Sie die Häufigkeit, mit der Nutzer den Agenten tatsächlich aufrufen:

time zsh -lic exit
time zsh -ic exit

Trace Ausführung von Dateien und Zeilen, wenn die Quelldatei unklar ist:

PS4='%N:%i> ' zsh -xlic exit

Führen Sie den Trace in einem sauberen Testkonto aus oder überprüfen Sie ihn vor dem Teilen: Startbefehle können Tokens sowie andere sensible Werte erweitern.

Bei einem fehlenden Ausführbaren prüfen Sie sowohl den Modus als auch den Pfad:

print -r -- "interactive=$options[interactive] login=$options[login]"
print -l -- $path
whence -va python node uv

Fazit

Der entscheidende Unterschied liegt nicht im Kontrast zwischen „Umgebung“ und „Aliasen“. Vielmehr geht es um den Zustand, der ausschließlich beim Anmelden existiert, im Gegensatz zum interaktiven Zustand, sowie um die geringe Menge an Informationen, die tatsächlich in jedem Zsh-Prozess berücksichtigt werden müssen.

Stellen Sie die Shell-Flags sicher, lassen Sie die Startdateien unbeeinflusst und platzieren Sie jeden generierten Hook dort, wo alle erforderlichen Funktionen vorhanden sind. Dadurch bleibt die Konfiguration unabhängig von den jeweiligen Terminal-Anwendungen – ohne vorgeben zu müssen, dass macOS und Linux jeweils nur einen festen Startmodus bieten.

Referenzen