
Verfolge jede Shell-Umgebungsvariable bis zu ihrem genauen Datei- und Zeilenursprung. Prüfe Shell-Konfigurationen auf tote Einträge, Duplikate und verwaiste Dateien in zsh und bash unter macOS, Linux und FreeBSD.
Finde für jede Variable in deiner aktuellen Shell die Datei und Zeile, die sie gesetzt hat — oder welches Subsystem (direnv, launchd, Terminal, SSH, System) sie injiziert hat. Dazu ein paar Befehle für statische Dateien für den Moment, in dem deine Shell-Konfiguration über N Dateien und Backups verstreut ist und du den Überblick verloren hast.
Ich habe das gebaut, weil ich alle paar Monate immer wieder dieselbe Stunde verlor, wenn ich herausfinden wollte, warum ein JAVA_HOME oder PATH auf etwas zeigte, das ich nicht erwartet hatte. which kennt Befehle, kennt direnv, kennt launchd — aber keines davon verrät dir, dass der eigentliche Schreiber ist.
direnv statuslaunchctl getenv~/.zshrc:42Funktioniert mit zsh und bash unter macOS, Linux und FreeBSD.
Ein grep -r JAVA_HOME ~ zeigt jede Datei, die die Variable erwähnt, aber aus der Ausgabe geht nicht eindeutig hervor, welche Zuweisung in der aktuellen Shell aktiv ist:
$ 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]
Einzeiler (erkennt OS/Architektur, legt die Binärdatei in deinen $PATH und deaktiviert Gatekeeper unter macOS):
curl -fsSL https://raw.githubusercontent.com/sreckoskocilic/envocabulary/main/install.sh | sh
Oder go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Vorgefertigte Binärdateien und Linux-Pakete (.deb / .rpm / .apk / .pkg.tar.zst) gibt es auf der Releases-Seite.
Live-Umgebung (untersucht deine laufende Shell):
scan (Standard) — gibt alle Variablen der aktuellen Umgebung gruppiert nach Herkunft ausexplain NAME — gibt die vollständige Zuordnung für die angegebene Variable auspath [VARNAME...] — Zuordnung pro Eintrag für durch Doppelpunkte getrennte Pfadvariablen; --check findet tote EinträgeStatische Dateien:
inventory — listet alle Shell-Konfigurationsdateien auf und zählt Definitionen nach Typcatalog — gibt die gesamte Shell-Konfiguration aus, indem alle Konfigurationsdateien zusammengeführt werdendedup — dateiübergreifender Duplikatsbericht für export-Anweisungen, Zuweisungen, Aliase und Funktionendangling — listet Konfigurationsdateieinträge auf, die kein gültiges Ziel mehr referenzierenlost — listet Definitionen auf, die nur in verwaisten/Backup-Konfigurationsdateien vorkommenreport — kombinierte Prüfung: sicher zu löschen, überprüfen (Duplikate mit geändertem Wert), dangling, verwaiste Dateien; --html schreibt eine mit Zeitstempel versehene .html-Datei in das aktuelle Verzeichnisclean [--full] DATEI — listet Zeilen auf, die entfernt werden sollen; mit --full wird der vollständige bereinigte Inhalt ausgegebenSonstiges:
-V, --version — gibt Version, Commit und Build-Datum ausenvocabulary <cmd> -h für Flags.
Die Beispielausgabe unten verwendet der Kürze halber ~/; das Tool gibt überall absolute Pfade aus, außer bei report.
dangling listet Konfigurationsdateieinträge auf, die kein gültiges Ziel mehr referenzieren — die Überbleibsel der Art JAVA_HOME=/opt/jdk-i-uninstalled und 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 zeigt, wo jeder Eintrag in PATH (oder MANPATH, FPATH usw.) eingeführt wurde:
$ 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
Einträge, die keiner Shell-Startzuweisung zugeordnet werden konnten, werden als inherited angezeigt.
--check filtert nach Einträgen, deren Verzeichnis nicht mehr existiert, und führt sie auf die zu bearbeitende Konfigurationsdatei zurück:
$ 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)
Beendet sich mit 1, wenn tote Einträge gefunden werden (nützlich in Skripten).
export EDITOR=vim VISUAL=vim erfasst nur EDITOR).dangling löst PATH-artige Zuweisungen oder Erweiterungen nicht auf (export GOPATH=$HOME/go).path-Zuordnung basiert auf xtrace-Diffs — die erste Zuweisung, die einen Eintrag enthält, beansprucht ihn, selbst wenn er über $PATH-Erweiterung weitergegeben statt explizit hinzugefügt wurde.envocabulary wird niemals unset, rm oder deine Shell-Konfiguration bearbeiten. Ein Notfallwerkzeug sollte nicht das Ding sein, das den Notfall verschlimmert. Wenn du aufräumen möchtest, kopiere die Datei:Zeile-Verweise und nimm die Änderungen selbst vor. clean gibt auf stdout aus; den Redirect machst du selbst.