[!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

Ficheiros de inicialização do Zsh selecionados para os modos de login e interativo

Uma shell pode ser:

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 é:

  1. $ZDOTDIR/.zshenv em cada invocação do Zsh $ZDOTDIR/.zprofile se a shell for uma shell de login $ZDOTDIR/.zshrc se a shell for interativa $ZDOTDIR/.zlogin se a shell for uma shell de login $ZDOTDIR/.zlogout quando 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.

Sequência de inicialização do Zsh para quatro modos de shell

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

FicheiroRegra de seleçãoBons candidatosEvite
.zshenvCada ZshVariáveis raras necessárias em todos os processos Zshsaída, aliases, prompts, chamadas de rede, comandos lentos
.zprofileShells de loginConfiguração do caminho da sessão de login e valores padrão exportadosganchos interativos, completamentos e associações de teclas
.zshrcShells interativosprompt, completação, aliases, opções de shell, ganchos de ferramentas interativassaída ou mutações destinadas a scripts
.zloginShells de login, após .zshrcAções raras de início de sessão pós-interativaconfiguração que deve ser aplicada primeiro .zshrc
.zlogoutSaída da shell de loginAções simples de limpeza ou redefinição do terminalEstado importante que deve sobreviver a falhas ou interrupções. exec

Manter .zshenv aborrecido

Cada elemento não interativo zsh -c.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:

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.

Referências