[!NOTE] Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.
Ficheiros de Inicialização do Zsh: ~/.zprofile versus ~/.zshrc em macOS e Linux
Se o seu terminal parecer lento, ou se uma variável de ambiente aparecer num terminal mas não noutro, a causa é frequentemente o modo de inicialização do Zsh. Os dois ficheiros aos quais a maioria das pessoas recorre são ~/.zprofile e ~/.zshrc, mas o nome do ficheiro por si só também não indica se uma linha pertence a ele.
O Zsh seleciona os ficheiros de inicialização com base em duas propriedades independentes: se a shell é uma shell de login e se ela é interativa. As aplicações de terminal no macOS e no Linux podem escolher combinações diferentes, pelo que deve verificar a shell em execução em vez de assumir que o sistema operativo toma essa decisão por si.
TL;DR. Coloque a inicialização da sessão de login em .zprofile e comportamento interativo em .zshrc. Mantenha .zshenv silencioso e mínimo. Não mova os ganchos interativos do gestor de versões para dentro .zprofile ou obter todo o perfil a partir da fonte .zshrc; inspecione o código gerado pela ferramenta e siga as instruções atuais do Zsh.
O Zsh avalia dois sinalizadores independentes
Uma shell pode ser:
- de login e interativo, tal como o Apple Terminal inicia normalmente o shell de login predefinido da conta
- sem login e interativo, como um aninhado
zshou muitas configurações de terminal Linux iniciam-no – em modo de login e não interativo, comozsh -lc 'command' - sem necessidade de login e não interativo, como
zsh -c 'command'
Aplicações terminais, IDEs, sessões remotas, multiplexadores e flags explícitos da shell podem selecionar diferentes modos. O sistema operativo, por si só, não determina o resultado.
Pergunte ao shell em execução em vez de adivinhar:
print -r -- "interactive=$options[interactive] login=$options[login]"
A ordem real de inicialização
Zsh lê primeiro os ficheiros globais e, em seguida, o ficheiro correspondente do utilizador. Com as definições padrão RCS Opções: a ordem dos ficheiros do utilizador é:
$ZDOTDIR/.zshenvem cada invocação do Zsh$ZDOTDIR/.zprofilese a shell for uma shell de login$ZDOTDIR/.zshrcse a shell for interativa$ZDOTDIR/.zloginse a shell for uma shell de login$ZDOTDIR/.zlogoutquando um shell de login termina normalmente
Se ZDOTDIR não está definido, o Zsh utiliza $HOME. As localizações dos ficheiros em todo o sistema são específicas de cada instalação; os valores predefinidos comuns são /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin, e /etc/zlogout.
A ordem de execução funciona como um filtro, e não como uma garantia ao longo do ciclo de vida. .zprofile É executado uma vez por processo de shell de login, e não uma vez por cada login no computador. Se cada nova aba de terminal iniciar uma shell de login, todas as abas irão lê-lo.
O que deve constar em cada ficheiro
| Ficheiro | Regra de seleção | Bons candidatos | Evite |
|---|---|---|---|
.zshenv | Cada Zsh | Variáveis raras necessárias em todos os processos Zsh | saída, aliases, prompts, chamadas de rede, comandos lentos |
.zprofile | Shells de login | Configuração do caminho da sessão de login e valores padrão exportados | ganchos interativos, completamentos e associações de teclas |
.zshrc | Shells interativos | prompt, completação, aliases, opções de shell, ganchos de ferramentas interativas | saída ou mutações destinadas a scripts |
.zlogin | Shells de login, após .zshrc | Ações raras de início de sessão pós-interativa | configuração que deve ser aplicada primeiro .zshrc |
.zlogout | Saída da shell de login | Ações simples de limpeza ou redefinição do terminal | Estado importante que deve sobreviver a falhas ou interrupções. exec |
Manter .zshenv aborrecido
Cada elemento não interativo zsh -c lê .zshenv. Um echo, uma chamada ao package-manager ou um subprocesso dispendioso pode corromper a saída do comando e abrandar os scripts. A maioria dos utilizadores precisa de pouco ou nada neste ficheiro.
Uma variável exportada em .zprofile É herdado pelos filhos dessa shell de login. Não é injetado automaticamente em aplicações GUI, serviços ou shells não relacionados cujo processo pai nunca leu o ficheiro.
Utilização .zprofile para uma configuração de acesso apenas por login
Um perfil pequeno pode definir valores padrão exportados e um caminho idempotente:
# ~/.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 Remova entradas duplicadas do array. Isso torna a obtenção repetida de dados mais segura, embora os ficheiros de inicialização ainda devam evitar trabalhos desnecessários.
Utilização .zshrc para o estado interativo
# ~/.zshrc
setopt auto_cd hist_ignore_all_dups share_history
autoload -Uz compinit
compinit
alias ll='ls -lah'
bindkey -e
Os aliases, os widgets de completamento, as tabelas de mapeamento de teclas, prompts e os ganchos de alteração de diretório pertencem à shell interativa que os utiliza.
Gestores de versão ultrapassam os limites simples de um ficheiro
“Utilizar gestores de versões em” .zprofile “porque são lentos” é um conselho pouco fiável. Um gestor de versões pode gerar vários tipos de código:
- um caminho estático ou variável raiz
- um caminho de shim de comando necessário para os processos filhos
- definições de completamento
- funções de shell que alteram o shell atual
- ganchos de alteração de diretório para troca automática de versão
As partes interativas devem estar presentes em todas as shells interativas, incluindo uma aninhada zsh lançado a partir de um editor. Atual fnm A documentação, portanto, descreve este gancho da seguinte forma: .zshrc:
eval "$(fnm env --use-on-cd --shell zsh)"
A documentação atual do pyenv também descreve a inicialização interativa completa em .zshrc:
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && path=("$PYENV_ROOT/bin" $path)
eval "$(pyenv init - zsh)"
Pyenv documenta um escopo mais restrito pyenv init --path modo para configuração de shim-path, mas completo pyenv init Instala também funcionalidades de completamento e funções de shell. Analise a documentação atual de uma ferramenta, bem como os resultados gerados, antes de proceder à sua divisão.
Se a inicialização for lenta, meça-a antes de mover o código para um modo em que ele já não funcione.
Não obtenha todo o perfil a partir de .zshrc
Uma solução alternativa comum em várias plataformas é:
# Avoid this blanket coupling.
source ~/.zprofile
Isso transforma ações exclusivas de login em ações específicas para cada shell interativo, permitindo repetir o arranque do agente, o acesso ao keychain, a saída de resultados ou a modificação de caminhos.
Se tanto as shells interativas de login como as de acesso não autenticado necessitarem de um pequeno conjunto de exportações estáticas, extraia um fragmento idempotente e inclua-o intencionalmente no código:
# ~/.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.
Este padrão mantém os dados partilhados separados dos efeitos colaterais relacionados com o login. Outra opção viável é configurar de forma consistente o gestor de terminais ou de sessões, em vez de suportar ambos os modos.
Diagnosticar o shell que está lento ou sem estado
Reproduza cada modo diretamente:
zsh -lic 'print "login interactive"'
zsh -ic 'print "non-login interactive"'
zsh -lc 'print "login non-interactive"'
zsh -c 'print "non-login non-interactive"'
Meça o modo que os utilizadores realmente iniciam:
time zsh -lic exit
time zsh -ic exit
Ficheiro de rasto e execução por linha quando a fonte não é clara:
PS4='%N:%i> ' zsh -xlic exit
Ejecute o rastreio numa conta de teste limpa ou inspecione-o antes de o partilhar: os comandos de arranque podem expandir tokens e outros valores sensíveis.
Para um executável ausente, verifique tanto o modo como o caminho:
print -r -- "interactive=$options[interactive] login=$options[login]"
print -l -- $path
whence -va python node uv
Conclusão
A distinção relevante não é “ambiente versus aliases”. Trata‑se de estado exclusivo para login versus estado interativo, além da pequena parte que realmente precisa afetar todos os processos Zsh.
Confirme as flags da shell, mantenha os ficheiros de arranque em silêncio e coloque cada gancho gerado onde todas as funcionalidades necessárias estiverem disponíveis. Isso torna a configuração portável entre aplicações de terminal, sem ser necessário assumir que o macOS e o Linux possuem um modo de arranque fixo próprio para cada sistema.