[!NOTE] Traducción automática Este artículo se tradujo automáticamente a partir de la versión original en inglés.

Archivos de inicio de Zsh: ~/.zprofile versus ~/.zshrc en macOS y Linux

Si tu terminal parece lenta, o una variable de entorno aparece en un terminal pero no en otro, la causa suele ser el modo de inicio de Zsh. Los dos archivos a los que recurren la mayoría de las personas son ~/.zprofile y ~/.zshrcPero ni el nombre del archivo por sí solo permite determinar si una línea pertenece a dicho archivo.

Zsh selecciona los archivos de inicio en función de dos propiedades independientes: si la shell es una shell de inicio de sesión y si es interactiva. Las aplicaciones de terminal en macOS y Linux pueden elegir diferentes combinaciones, por lo que es necesario inspeccionar la shell en ejecución en lugar de asumir que el sistema operativo toma esa decisión por usted.

Resumen. Colocar la inicialización de la sesión de inicio de sesión en .zprofile y el comportamiento interactivo en .zshrc. Mantener .zshenv Silencioso y mínimo. No mueva los ganchos interactivos del gestor de versiones hacia adentro .zprofile o obtener todo el perfil desde la fuente .zshrc; inspeccione el código generado por la herramienta y siga sus instrucciones actuales en Zsh.

Zsh evalúa dos indicadores independientes

Archivos de inicio de Zsh seleccionados según los modos de inicio de sesión e interactivo

Un shell puede ser:

Las aplicaciones de terminal, los IDE, las sesiones remotas, los multiplexores y las banderas explícitas de la shell pueden seleccionar diferentes modos. El sistema operativo por sí solo no determina el resultado.

Pregunte al shell en ejecución en lugar de adivinar:

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

El orden real de inicio

Zsh lee primero los archivos globales y, a continuación, el archivo correspondiente del usuario. Con la configuración predeterminada RCS En cuanto a las opciones, el orden de los archivos del usuario es:

  1. $ZDOTDIR/.zshenv en cada invocación de Zsh $ZDOTDIR/.zprofile si el shell es un shell de inicio de sesión $ZDOTDIR/.zshrc si la shell es interactiva
  2. $ZDOTDIR/.zlogin si el shell es un shell de inicio de sesión $ZDOTDIR/.zlogout cuando una shell de inicio de sesión finaliza de forma normal

Si ZDOTDIR no está definido, Zsh utiliza $HOME. Las ubicaciones de los archivos a nivel del sistema son específicas de cada instalación; los valores predeterminados comunes son /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin, y /etc/zlogout.

Secuencia de inicio de Zsh para cuatro modos de shell

Dicho ordenamiento constituye un filtro, y no una garantía relacionada con el ciclo de vida del modelo. .zprofile Se ejecuta una vez por proceso de shell de inicio de sesión, y no una vez por cada inicio de sesión en el ordenador. Dado que cada nueva pestaña de terminal inicia un shell de inicio de sesión, todas las pestañas lo leerán.

Qué debe contener cada archivo

ArchivoRegla de selecciónBuenos candidatosEvitar
.zshenvCada ZshVariables poco comunes requeridas por cada proceso de Zshsalida, alias, prompts, llamadas de red, comandos lentos
.zprofileShells de inicio de sesiónConfiguración de la ruta de sesión de inicio de sesión y valores predeterminados exportadosganchos interactivos, completaciones y asignaciones de teclas
.zshrcSesiones interactivasprompt: completación, alias, opciones de shell e puntos de conexión para herramientas interactivasSalida o mutaciones destinadas a los scripts
.zloginLos shells de inicio de sesión, después de .zshrcAcciones de inicio de sesión poco frecuentes posteriores a la interacciónconfiguración que debe anteceder .zshrc
.zlogoutSalida de la shell de inicio de sesiónAcciones de limpieza mínima o reinicio del terminalEstado importante que debe mantenerse intacto tras fallos o caídas del sistema. exec

Mantener .zshenv aburrido

Cada elemento no interactivo zsh -c lee .zshenv. Un echo, una llamada al gestor de paquetes o un subproceso costoso pueden corromper la salida de los comandos y ralentizar los scripts. La mayoría de los usuarios solo necesitan poco o nada en este archivo.

una variable exportada en .zprofile Es heredado por los hijos de dicha shell de inicio de sesión. No se inyecta automáticamente en aplicaciones GUI, servicios o shells no relacionados cuyo proceso padre nunca haya leído el archivo.

Uso .zprofile para una configuración de acceso exclusivo mediante inicio de sesión

Un perfil reducido puede definir valores predeterminados exportados y una ruta 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 Elimina las entradas duplicadas del array. Esto hace que la obtención repetida de datos sea más segura, aunque los archivos de inicialización deben seguir evitando realizar operaciones innecesarias.

Uso .zshrc para el estado interactivo

# ~/.zshrc
setopt auto_cd hist_ignore_all_dups share_history

autoload -Uz compinit
compinit

alias ll='ls -lah'
bindkey -e

Los alias, los widgets de completado, las tablas de mapeo de teclas, prompts y los ganchos de cambio de directorio forman parte del shell interactivo que los utiliza.

Los gestores de versiones trascienden los límites simples de los archivos

“Integren gestores de versiones en” .zprofile “Porque son lentos” es un consejo poco fiable. Un gestor de versiones puede generar varios tipos de código:

Las partes interactivas deben estar presentes en cada shell interactivo, incluyendo uno anidado. zsh lanzado desde un editor. Actual fnm Por lo tanto, la documentación coloca este gancho en .zshrc:

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

La documentación actual de pyenv también describe la inicialización interactiva completa en .zshrc:

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

Pyenv documenta un rango más restringido pyenv init --path modo para la configuración de shim-path, pero completo pyenv init También instala funciones de completado y de shell. Inspecciona la documentación actual del herramienta, así como su salida generada, antes de dividirla.

Si la inicialización es lenta, mézclala antes de pasar el código a un modo en el que ya no funcione.

No se debe obtener toda la información del perfil desde .zshrc

Una solución práctica común en múltiples plataformas es:

# Avoid this blanket coupling.
source ~/.zprofile

Esto convierte las acciones exclusivas de inicio de sesión en acciones específicas para cada shell interactiva, y permite repetir el inicio del agente, el acceso al keychain, la obtención de resultados o la modificación de rutas.

Si tanto las shells interactivas de inicio de sesión como las sin él necesitan un conjunto reducido de exportaciones estáticas, extraiga un fragmento idempotente y cárguelo de forma intencionada:

# ~/.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 patrón mantiene los datos compartidos separados de los efectos secundarios relacionados con el inicio de sesión. Otra opción válida es configurar de forma consistente el gestor de terminales o sesiones, en lugar de soportar ambos modos.

Diagnosticar la shell que es lenta o carece de estado

Reproducir cada modo directamente:

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

Mida el modo que realmente utilizan los usuarios:

time zsh -lic exit
time zsh -ic exit

Archivo de trazado y ejecución por línea cuando el código fuente es poco claro:

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

Ejecuta el seguimiento en una cuenta de prueba limpia o inspéralo antes de compartirlo: los comandos de inicio pueden expandir tokens y otros valores sensibles.

Para un ejecutable ausente, inspeccione tanto el modo como la ruta:

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

Conclusión

La distinción relevante no es “entorno versus aliases”, sino el estado exclusivo para el inicio de sesión frente al estado interactivo, además de esa pequeña cantidad de elementos que realmente deben afectar a todos los procesos de Zsh.

Confirme los parámetros de la shell, mantenga en silencio los archivos de inicio y coloque cada gancho generado en el lugar donde se encuentren todas las funcionalidades que requiere. De este modo, la configuración será portable entre aplicaciones de terminal, sin tener que asumir que macOS y Linux cuenten con un modo de inicio fijo propio.

Referencias