
Tracez chaque variable d'environnement shell jusqu'à son fichier et sa ligne d'origine exacts. Auditez les configurations shell pour repérer les entrées mortes, les doublons et les fichiers orphelins sur zsh et bash sous macOS, Linux et FreeBSD.
Pour chaque variable de votre shell actuel, trouvez le fichier et la ligne qui l'ont définie — ou quel sous-système (direnv, launchd, terminal, SSH, système) l'a injectée. Plus quelques commandes sur fichiers statiques pour le moment où votre configuration shell s'est éparpillée sur N fichiers et sauvegardes et que vous avez perdu le fil.
J'ai construit cet outil parce que je perdais régulièrement une heure tous les deux ou trois mois à chercher pourquoi un JAVA_HOME ou un PATH pointait vers un endroit inattendu. which connaît les commandes, direnv status connaît direnv, launchctl getenv connaît launchd — aucun d'entre eux ne vous indique que ~/.zshrc:42 est le véritable responsable.
Fonctionne avec zsh et bash sur macOS, Linux et FreeBSD.
Un grep -r JAVA_HOME ~ affichera tous les fichiers qui mentionnent la variable, mais la sortie ne précise pas quelle affectation est active dans le shell actuel :
$ envocabulary explain --chain JAVA_HOME
JAVA_HOME
origin shell-file
primary ~/helpers.sh:3
chain ~/.zshrc → ~/helpers.sh
writers
~/.zshenv:8
~/helpers.sh:3 (winner)
value [hidden, use --values]
Commande en une ligne (détecte l'OS/architecture, dépose le binaire dans votre $PATH, désactive Gatekeeper sur macOS) :
curl -fsSL https://raw.githubusercontent.com/sreckoskocilic/envocabulary/main/install.sh | sh
Ou go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Des binaires précompilés et des paquets Linux (.deb / .rpm / .apk / .pkg.tar.zst) sont disponibles sur la page des versions.
Environnement en direct (inspecte votre shell en cours d'exécution) :
scan (par défaut) — affiche toutes les variables de l'environnement actuel regroupées par origineexplain NAME — affiche l'attribution complète pour la variable fourniepath [VARNAME...] — attribution par entrée pour les variables de chemin séparées par des deux-points ; --check détecte les entrées mortesFichiers statiques :
inventory — liste tous les fichiers de configuration shell et compte les définitions par typecatalog — affiche l'intégralité de la configuration shell en fusionnant tous ses fichiers de configurationdedup — rapport des doublons entre fichiers pour les exports, affectations, alias et fonctionsdangling — liste les entrées des fichiers de configuration qui ne référencent plus de cible validelost — liste les définitions propres aux fichiers de configuration orphelins ou de sauvegardereport — audit combiné : supprimables sans risque, à examiner (doublons dont la valeur a changé), entrées orphelines, fichiers orphelins ; --html écrit un fichier .html horodaté dans le répertoire courantclean [--full] FILE — liste les lignes à supprimer ; avec --full, affiche le contenu nettoyé completAutres :
-V, --version — affiche la version, le commit et la date de compilationenvocabulary <cmd> -h pour les options.
Les exemples de sortie ci-dessous utilisent ~/ par souci de concision ; l'outil affiche des chemins absolus partout, sauf pour report.
dangling liste les entrées des fichiers de configuration qui ne référencent plus de cible valide — le genre de restes comme JAVA_HOME=/opt/jdk-i-uninstalled et source ~/dotfiles/work-old.zsh :
$ envocabulary dangling
## ~/.zshrc
~/.zshrc:14 source → ~/dotfiles/work-old.zsh (source target missing)
~/.zshrc:42 export JAVA_HOME → /opt/jdk-11 (path does not exist)
path montre où chaque entrée de PATH (ou MANPATH, FPATH, etc.) a été introduite :
$ envocabulary path PATH
## PATH
/opt/homebrew/bin ~/.zprofile:21
/usr/local/bin ~/.zprofile:1
/usr/bin /etc/zprofile:1
/bin /etc/zprofile:1
/usr/sbin /etc/zprofile:1
/sbin /etc/zprofile:1
~/.cargo/bin ~/.zshrc:22
Les entrées qui ne correspondent à aucune affectation de démarrage du shell sont affichées comme inherited.
--check filtre pour ne conserver que les entrées dont le répertoire n'existe plus et les relie au fichier de configuration à modifier :
$ envocabulary path --check PATH
## PATH
/opt/homebrew/Cellar/go/1.25.1/libexec/bin ~/.zshrc:17 (does not exist)
/opt/pkg/env/active/bin /etc/paths.d/10-pmk-global:1 (does not exist)
/Applications/VMware /etc/paths.d/com.vmware.fusion.public:1 (does not exist)
Quitte avec le code 1 lorsque des entrées mortes sont trouvées (utile dans les scripts).
export EDITOR=vim VISUAL=vim n'enregistre que EDITOR).dangling ne résout pas les affectations de type PATH ni les expansions (export GOPATH=$HOME/go).path repose sur les diffs xtrace — la première affectation qui inclut une entrée s'en attribue la paternité, même si celle-ci a été reportée via l'expansion de $PATH plutôt qu'ajoutée explicitement.envocabulary ne fera jamais unset, rm ni ne modifiera votre configuration shell. Un outil d'urgence ne devrait pas être ce qui aggrave l'urgence. Si vous voulez nettoyer, copiez les pointeurs file:line et faites les modifications vous-même. clean écrit sur stdout ; c'est à vous de faire la redirection.