[!NOTE] Traduction automatique Cet article a été traduit automatiquement depuis la version originale en anglais.
Fichiers de démarrage de Zsh : ~/.zprofile vs ~/.zshrc sur macOS et Linux
Si votre terminal semble lent, ou si une variable d’environnement apparaît dans un terminal mais pas dans un autre, la cause est souvent le mode de démarrage de Zsh. Les deux fichiers auxquels la plupart des utilisateurs se tournent sont ~/.zprofile et ~/.zshrcCependant, le nom de fichier seul ne permet pas non plus de déterminer si une ligne doit y figurer.
Zsh sélectionne les fichiers de démarrage en se basant sur deux critères indépendants : le fait que la shell soit une shell de connexion et qu’elle soit interactive. Les applications de terminal sous macOS et Linux peuvent choisir des combinaisons différentes ; il convient donc d’examiner la shell en cours d’exécution plutôt que de supposer que c’est le système d’exploitation qui prend cette décision à votre place.
TL;DR. Placer l’initialisation de la session de connexion dans
.zprofileainsi que le comportement interactif dans.zshrc. Conserver.zshenvsilencieux et minimaliste. Ne déplacez pas les hooks interactifs du gestionnaire de versions à l’intérieur.zprofileou charger l’ensemble du profil depuis.zshrc; Vérifiez le code généré par l’outil et suivez ses instructions Zsh actuelles.
Zsh évalue deux flags indépendants
Un shell peut être :
- en mode connexion et interactif, car le Terminal d’Apple lance normalement le shell de connexion par défaut du compte
- en mode hors connexion et interactif, en tant que structure imbriquée
zshou encore de nombreuses configurations de terminal Linux le lancent – en mode connexion et en mode non interactifzsh -lc 'command' - sans connexion et non interactif, comme
zsh -c 'command'
Les applications en ligne de commande, les IDE, les sessions distantes, les multiplexeurs ainsi que les flags explicites du shell peuvent sélectionner différents modes. Le système d’exploitation seul ne détermine pas le résultat.
Demandez à la shell en cours d’exécution plutôt que de deviner :
print -r -- "interactive=$options[interactive] login=$options[login]"
L’ordre réel de démarrage
Zsh lit d’abord les fichiers globaux, puis le fichier utilisateur correspondant. Avec la configuration par défaut RCS Options : l’ordre des fichiers utilisateurs est le suivant :
$ZDOTDIR/.zshenvpour chaque invocation de Zsh$ZDOTDIR/.zprofilesi le shell est un shell de connexion$ZDOTDIR/.zshrcsi le shell est interactif$ZDOTDIR/.zloginsi le shell est un shell de connexion$ZDOTDIR/.zlogoutlorsqu’un shell de connexion se termine normalement
Si ZDOTDIR n’est pas défini, Zsh utilise $HOME. Les emplacements des fichiers à l’échelle du système sont spécifiques à chaque installation ; les valeurs par défaut courantes sont /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin, et /etc/zlogout.
Cette commande constitue un filtre, et non une garantie de cycle de vie. .zprofile Il s’exécute une fois par processus de shell de connexion, et non une fois par connexion au poste de travail. Puisque chaque nouvelle fenêtre de terminal lance une shell de connexion, chacune d’elles la lit.
Quelles éléments doivent figurer dans chaque fichier
| Fichier | Règle de sélection | De bons candidats | Éviter |
|---|---|---|---|
.zshenv | Chaque Zsh | Variables rares requises par chaque processus Zsh | sortie, alias, prompts, appels réseau, commandes lentes |
.zprofile | Shells de connexion | Configuration du chemin de la session de connexion et valeurs par défaut exportées | des goupilles interactives, des complétions et des raccourcis clavier |
.zshrc | Bourreaux interactifs | prompt : complétion, alias, options de shell, points d’ancrage pour des outils interactifs | Les sorties ou mutations destinées aux scripts |
.zlogin | Les shells de connexion, après .zshrc | Actions de connexion rares après interaction utilisateur | configuration qui doit précéder .zshrc |
.zlogout | Sortie de la shell de connexion | petites opérations de nettoyage ou de réinitialisation du terminal | État critique qui doit persister en cas de panne ou d’erreur. exec |
Conserver .zshenv ennuyeux
Chaque élément non interactif zsh -c lit .zshenv. Un echoUne invocation du gestionnaire de paquets, ou un sous-processus coûteux, peut corrompre la sortie des commandes et ralentir les scripts. La plupart des utilisateurs n’ont besoin que de très peu, voire de rien, dans ce fichier.
Une variable exportée dans .zprofile Il est hérité par les enfants de cette shell de connexion. Il n’est pas injecté automatiquement dans des applications GUI, des services ou des shells non apparentés dont le processus parent n’a jamais lu ce fichier.
Utilisation .zprofile pour une configuration réservée uniquement à la connexion
Un profil réduit peut définir des valeurs par défaut exportées ainsi qu’un chemin idempotent :
# ~/.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 Il supprime les éléments dupliqués de l’array. Cela rend la récupération répétée des données plus fiable, bien que les fichiers de démarrage doivent néanmoins éviter tout travail inutile.
Utilisation .zshrc pour l’état interactif
# ~/.zshrc
setopt auto_cd hist_ignore_all_dups share_history
autoload -Uz compinit
compinit
alias ll='ls -lah'
bindkey -e
Les alias, les widgets de complétion, les mappages de touches, prompts, ainsi que les hooks de changement de répertoire font partie du shell interactif qui les utilise.
Les gestionnaires de versions franchissent les limites simples des fichiers
« Intégrez des gestionnaires de versions dans » .zprofile Car ils sont lents” constitue un conseil peu fiable. Un gestionnaire de versions peut générer plusieurs types de code :
- un chemin statique ou une variable racine
- un chemin de shim de commande requis par les processus enfants
- des définitions de complétion
- des fonctions de shell qui modifient le shell actuel
- des hooks de changement de répertoire pour un basculement automatique de version
Les parties interactives doivent être présentes dans chaque shell interactif, y compris ceux qui sont imbriqués. zsh démarré depuis un éditeur. Actuel fnm La documentation place donc ce hook à cet endroit. .zshrc:
eval "$(fnm env --use-on-cd --shell zsh)"
La documentation actuelle de pyenv propose également une initialisation interactive complète en .zshrc:
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && path=("$PYENV_ROOT/bin" $path)
eval "$(pyenv init - zsh)"
Pyenv documente un champ plus restreint pyenv init --path mode pour la configuration de shim-path, mais complet pyenv init Il installe également des fonctionnalités de complétion ainsi que des fonctions de shell. Examinez la documentation actuelle d’une outil et les résultats générés avant de le diviser.
Si le démarrage est lent, mesurez-le avant de transférer le code dans un mode où il cesse de fonctionner.
Ne pas récupérer l’ensemble du profil depuis .zshrc
Une solution de contournement courante sur plusieurs plateformes est :
# Avoid this blanket coupling.
source ~/.zprofile
Cela transforme les actions réservées à la connexion en actions spécifiques à chaque shell interactif, et permet de répéter le démarrage de l’agent, l’accès au trousseau de clés, l’affichage des résultats ou la modification des chemins.
Si tant les shells interactifs en mode connexion que ceux hors connexion nécessitent un petit ensemble d’exports statiques, extrayez un fragment idempotent et chargez-le délibérément :
# ~/.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.
Ce schéma permet de séparer les données partagées des effets secondaires liés à la connexion. Une autre option valable consiste à configurer de manière cohérente le gestionnaire de terminaux ou de sessions, plutôt que de prendre en charge les deux modes en même temps.
Diagnostiquer le shell qui présente des lenteurs ou un manque d’état
Reproduisez chaque mode directement :
zsh -lic 'print "login interactive"'
zsh -ic 'print "non-login interactive"'
zsh -lc 'print "login non-interactive"'
zsh -c 'print "non-login non-interactive"'
Mesurer le mode d’exécution réellement utilisé par les utilisateurs :
time zsh -lic exit
time zsh -ic exit
Fichier de trace et suivi de l’exécution ligne par ligne lorsque la source est peu claire :
PS4='%N:%i> ' zsh -xlic exit
Exécutez le suivi sur un compte de test propre ou examinez-le avant de le partager : les commandes de démarrage peuvent déployer des tokens ainsi que d’autres valeurs sensibles.
Pour un exécutable manquant, vérifiez à la fois le mode et le chemin :
print -r -- "interactive=$options[interactive] login=$options[login]"
print -l -- $path
whence -va python node uv
Conclusion
La distinction pertinente n’est pas « environnement contre alias ». Il s’agit plutôt de l’état réservé à la connexion contre l’état interactif, ainsi que de la petite partie de données qui doit réellement impacter chaque processus Zsh.
Vérifiez les flags de la shell, assurez-vous que les fichiers de démarrage restent silencieux, et placez chaque crochet généré là où se trouvent toutes les fonctionnalités nécessaires. Cela permet à la configuration d’être portable entre les applications de terminal, sans prétendre que macOS et Linux disposent chacun d’un mode de lancement fixe.