[!NOTE] Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.
Zsh-startopbestanden: ~/.zprofile vs ~/.zshrc op macOS en Linux
Als je terminal traag aanvoelt, of wanneer een omgevingsvariabele in de ene terminal wel verschijnt maar niet in een andere, ligt de oorzaak vaak bij de startmodus van Zsh. De twee bestanden waarna de meeste mensen op zoek gaan zijn ~/.zprofile en ~/.zshrcMaar zelfs de bestandsnaam alleen geeft geen indicatie of een regel daarin thuishoort.
Zsh kiest de startbestanden op basis van twee onafhankelijke eigenschappen: of het shell een login shell is en of het interactief is. Terminaltoepassingen op macOS en Linux kunnen verschillende combinaties kiezen; controleer daarom de actieve shell in plaats van te veronderstellen dat het besturingssysteem dit voor u beslist.
TL;DR. Plaats de initialisatie van het inlogproces-session in
.zprofileen interactief gedrag in.zshrc. Houd aan..zshenvstil en minimaal. Verplaats de interactieve hooks van de versiebeheerder niet naar binnen.zprofileof haal het hele profiel rechtstreeks op van.zshrc; Controleer de door het hulpprogramma gegenereerde code en volg de huidige instructies van Zsh.
Zsh evalueert twee onafhankelijke flaggen
Een shell kan zijn:
- Inloggen en interactief, aangezien Apple Terminal normaal gesproken de standaard inlogshell van het account start
- Zonder inloggen en interactief, als een genest structuur
zshof door veel Linux-terminalconfiguraties wordt het gestart – zowel voor inloggen als voor niet-interactieve toepassingenzsh -lc 'command' - zonder inloggen en niet-interactief, aangezien
zsh -c 'command'
Terminaltoepassingen, IDE’s, externe sessions, multiplexers en expliciete shellflags kunnen verschillende modi kiezen. Het besturingssysteem alleen bepaalt het resultaat niet.
Vraag het lopende shell in plaats van te gissen:
print -r -- "interactive=$options[interactive] login=$options[login]"
De daadwerkelijke opstartvolgorde
Zsh leest eerst de globale bestanden en daarna de overeenkomstige gebruikersbestanden. Met de standaardinstellingen RCS Opties: de volgorde van de gebruikersbestanden is:
$ZDOTDIR/.zshenvvoor elke oproep van Zsh$ZDOTDIR/.zprofileals de shell een login-shell is$ZDOTDIR/.zshrcals de shell interactief is$ZDOTDIR/.zloginals de shell een login-shell is$ZDOTDIR/.zlogoutwanneer een inlogshell normaal wordt afgesloten
Als ZDOTDIR is niet ingesteld, Zsh gebruikt $HOME. De systeemwijde bestandspaden zijn specifiek voor elke installatie; de gebruikelijke standaardwaarden zijn /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin, en /etc/zlogout.
De opdracht fungeert als een filter en biedt geen garantie voor de levenscyclus. .zprofile Het wordt één keer uitgevoerd per login-shell-proces, en niet één keer bij elke computerlogin. Aangezien elk nieuw terminaltabblad een login shell start, wordt het bestand door elk tabblad gelezen.
Wat hoort er in elk bestand
| Bestand | Selectieregel | Goede kandidaten | Vermeed |
|---|---|---|---|
.zshenv | Elk Zsh | Zeldzame variabelen die door elk Zsh-proces vereist zijn | uitvoer, aliasen, prompts, netwerkoproepen, trage commando’s |
.zprofile | Inlogschillen | Inloggen – instellingen van de session-paden en geëxporteerde standaardwaarden | interactieve hooks, voltooien van invoer, toetsbindingen |
.zshrc | Interactieve shells | prompt, voltooiing, aliasen, shell-opties, interactieve hulphooks | Uitvoer of mutaties die bedoeld zijn voor scripts |
.zlogin | Inlogschelpen, na .zshrc | Zeldzame acties bij inloggen na interactie | configuratie die vooraf moet gaan .zshrc |
.zlogout | Vertrek uit de inlogshell | Kleine opmaakacties of acties ter herstel van de terminal | belangrijke toestand die moet overleven bij crashes of exec |
Bewaren .zshenv saai
Elk niet-interactief element zsh -c leest .zshenv. Een echoEen oproep van de package-manager of een dure subprocess kan de uitvoer van een commando beschadigen en scripts vertragen. De meeste gebruikers hebben weinig of helemaal niets in dit bestand nodig.
Een geëxporteerde variabele in .zprofile Het wordt geërfd door de kindprocessen van die login-shell. Het wordt niet automatisch ingevoegd in ongerelateerde GUI-applicaties, diensten of shells wier ouderproces het bestand nooit heeft gelezen.
Gebruik .zprofile voor een configuratie die alleen voor inloggen is bedoeld
Een klein profiel kan geëxporteerde standaardwaarden en een idempotente route definiëren:
# ~/.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 Het verwijdert dubbele elementen uit het array. Hierdoor wordt herhaaldelijk ophalen van gegevens veiliger, hoewel startbestanden toch onnodige bewerkingen moeten vermijden.
Gebruik .zshrc voor interactieve staat
# ~/.zshrc
setopt auto_cd hist_ignore_all_dups share_history
autoload -Uz compinit
compinit
alias ll='ls -lah'
bindkey -e
Aliassen, vulwidgets, toetsenbordmappen, prompts, en hooks voor het wijzigen van de map maken deel uit van de interactieve shell die ze gebruikt.
Versiebeheerders overstijgen de eenvoudige bestandsgrens
“Plaats versiebeheerders in” .zprofile “Omdat ze traag zijn” is onbetrouwbare advies. Een versiebeheerder kan verschillende soorten code genereren:
- een statische pad of root-variabele
- een command-shim-pad dat nodig is voor kindprocessen
- definities voor voltooiing
- shell-functies die de huidige shell wijzigen
- hooks voor het wijzigen van mappen voor automatische versienwisseling
De interactieve onderdelen moeten in elke interactieve shell aanwezig zijn, inclusief een genestelde zsh gestart vanuit een editor. Huidig fnm De documentatie plaatst deze hook dus op deze locatie. .zshrc:
eval "$(fnm env --use-on-cd --shell zsh)"
De huidige documentatie van pyenv plaatst eveneens de volledige interactieve initialisatie in .zshrc:
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && path=("$PYENV_ROOT/bin" $path)
eval "$(pyenv init - zsh)"
Pyenv documenteert een smaller bereik. pyenv init --path Modus voor de configuratie van shim-paden, maar volledig pyenv init Het installeert tevens functies voor automatische completering en shell-functies. Controleer eerst de huidige documentatie en de gegenereerde uitvoer van een hulpmiddel voordat u deze splitst.
Als de opstarttijd traag is, meet deze dan voordat je de code naar een modus verplaatst waarin deze niet langer functioneert.
Haal het hele profiel niet uit een externe bron .zshrc
Een veelgebruikte oplossing die op meerdere platforms werkt, is:
# Avoid this blanket coupling.
source ~/.zprofile
Dit zorgt ervoor dat acties die alleen bij inloggen worden uitgevoerd, worden omgezet in acties per interactieve shell, waardoor herhaalde agent-acties zoals opstarten, toegang tot het sleutelbos, weergeven van output of wijzigen van paden mogelijk zijn.
Als zowel de inloggende als de niet-inloggende interactieve shells een klein aantal statische exports nodig hebben, haal dan een idempotent fragment eruit en importeer dit bewust:
# ~/.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.
Dit patroon houdt de gedeelde gegevens gescheiden van de gevolgen van het inloggen. Een andere haalbare optie is om de terminal of de session-manager consequent in te stellen, in plaats van beide modi te ondersteunen.
Diagnoseer de shell die traag is of geen status weergeeft
Reproduceer elke modus direct:
zsh -lic 'print "login interactive"'
zsh -ic 'print "non-login interactive"'
zsh -lc 'print "login non-interactive"'
zsh -c 'print "non-login non-interactive"'
Meet de modus die gebruikers daadwerkelijk starten:
time zsh -lic exit
time zsh -ic exit
Trace uitvoering van bestanden en regels wanneer de bron onduidelijk is:
PS4='%N:%i> ' zsh -xlic exit
Voer trace uit in een schone testaccount of controleer het eerst voordat u het deelt: opstartcommando’s kunnen tokens en andere gevoelige waarden onthullen.
Voor een ontbrekend uitvoerbaar bestand, controleer zowel de modus als het pad:
print -r -- "interactive=$options[interactive] login=$options[login]"
print -l -- $path
whence -va python node uv
Conclusie
De relevante onderscheiding ligt niet tussen “omgeving versus alias”. Het gaat om de staat die alleen bestaat tijdens inloggen versus de interactieve staat, plus die kleine hoeveelheid elementen die daadwerkelijk invloed moeten hebben op elke Zsh-process.
Bevestig de shell-opties, houd de startbestanden stil en plaats elke gegenereerde hook op een locatie waar al zijn benodigde functies aanwezig zijn. Hierdoor blijft de configuratie bruikbaar in verschillende terminaltoepassingen, zonder te doen alsof macOS en Linux elk een vaste startmodus hebben.