
envocabulary v1.0.5
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.
envocabulary
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 dieselbe Stunde damit verbracht habe, nachzuvollziehen, warum irgendein JAVA_HOME oder PATH auf etwas zeigte, das ich nicht erwartet hatte. which kennt Befehle, direnv status kennt direnv, launchctl getenv kennt launchd. Keines davon sagt dir, dass ~/.zshrc:42 der tatsächliche Verursacher ist.
Funktioniert mit zsh und bash auf macOS, Linux und FreeBSD. Die Beispielausgabe unten verwendet ~/ der Kürze wegen; das Tool gibt überall absolute Pfade aus, außer bei report.
Der „Aha"-Moment
grep -r JAVA_HOME ~ zeigt jede Datei, die die Variable erwähnt. Es sagt dir nicht, welche Zuweisung in der Shell, in der du gerade sitzt, gewonnen hat:
$ 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]
Variablen, die durch eval "$(brew shellenv)", eval "$(pyenv init -)" und ähnliches gesetzt werden, zeigen auf die eval-Zeile. Der generierte Code hat keine eigene Zeile; das eval ist das, was du in einem Editor öffnen kannst.
Installation
curl -fsSL https://raw.githubusercontent.com/sreckoskocilic/envocabulary/main/install.sh | sh
Das Skript erkennt OS und Architektur, lädt das Release-Archiv herunter, verifiziert dessen sha256-Prüfsumme und verifiziert die cosign-Signatur, wenn cosign installiert ist. Es installiert nach /usr/local/bin, wenn dieses beschreibbar ist, andernfalls nach ~/.local/bin, und warnt, wenn dieses Verzeichnis nicht in deinem $PATH liegt. Unter macOS löscht es außerdem das Gatekeeper-Quarantäne-Flag.
Optionen: sh -s -- --version v1.0.4, um eine Version festzulegen, --bin-dir DIR, um das Zielverzeichnis zu wählen.
Oder go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Beachte, dass ein go install-Build für --version dev meldet; nur Release-Binaries tragen die Version, den Commit und das Build-Datum.
Vorgefertigte Binaries und Linux-Pakete (.deb / .rpm / .apk / .pkg.tar.zst) findest du auf der Releases-Seite.
Befehle
Live-Umgebung (liest deine laufende Shell):
scan(Standard) — gibt alle Variablen in der aktuellen Umgebung gruppiert nach Ursprung ausexplain NAME— vollständige Zuordnung für eine Variablepath [VARNAME...]— Zuordnung pro Eintrag für doppelpunktgetrennte Pfadvariablen;--checkfindet tote Einträge
Statische Dateien:
inventory— listet die Shell-Konfigurationsdateien in$HOMEauf (die kanonischen plus Backup-Varianten wie.zshrc.bak) und zählt Definitionen nach Typcatalog— gibt diese Dateien aneinandergehängt in der Reihenfolge aus, in der die Shell sie liestdedup— Duplikatbericht für exports, assigns, aliases, functions, innerhalb und über Dateien hinwegdangling— listet Konfigurationseinträge auf, deren Ziel nicht mehr existiert; beendet mit 1, wenn welche gefunden werdenlost— listet Definitionen auf, die nur in verwaisten/Backup-Dateien existierenreport— kombiniertes Audit: sicher zu löschen, prüfen (Duplikate mit abweichendem Wert, plus alle doppelten Funktionen), dangling, verwaiste Dateien;--htmlschreibt eine zeitgestempelte.html-Datei in das aktuelle Verzeichnisclean [--full] FILE— listet Kommentarzeilen auf, die entfernt würden; mit--fullwird der bereinigte Inhalt ausgegeben
Sonstiges:
-V,--version— gibt Version, Commit und Build-Datum aus
envocabulary <cmd> -h für Flags.
Exit-Codes: 0 bei Erfolg, 1 bei einem Laufzeitfehler oder wenn dangling / path --check etwas finden, 2 bei einem Nutzungsfehler.
Kaputte Referenzen finden
dangling listet Konfigurationseinträge auf, die auf nichts mehr zeigen, die Art von Überbleibseln wie 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-Einträge nachverfolgen
path zeigt, wo jeder Eintrag in PATH (oder MANPATH, FPATH usw.) eingeführt wurde:
$ envocabulary path PATH
## PATH
/opt/homebrew/bin ~/.zprofile:6
/opt/homebrew/sbin ~/.zprofile:6
/usr/local/bin /etc/zprofile:11
/usr/bin inherited
/bin inherited
~/.cargo/bin ~/.zshrc:22
Einträge, die keiner Shell-Startup-Zuweisung zugeordnet werden können, erscheinen als inherited. Das umfasst immer /usr/bin, /bin, /usr/sbin und /sbin: Sie sind der Ausgangspunkt, von dem der Tracer startet, nicht etwas, das eine Datei hinzugefügt hat.
--check filtert auf Einträge, deren Verzeichnis nicht mehr existiert, und löst die Quelle erneut gegen deine Dotfiles und /etc/paths.d auf, sodass es auf die zu bearbeitende Zeile zeigt:
$ 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 mit 1, wenn tote Einträge gefunden werden, was es in Skripten nutzbar macht.
Einschränkungen
- Eine Zuweisung pro Zeile:
export EDITOR=vim VISUAL=vimerfasst nurEDITOR. - Die statischen Befehle betrachten nur die kanonischen Dotfiles in
$HOME(.zshenv,.zprofile,.zshrc,.zlogin,.zlogout,.bashrc,.bash_profile,.profile) und deren Varianten im Stil.bak/.old. Sie folgen weder$ZDOTDIR,~/.config/zsh,/etcnoch Dateien, die dusourcest. danglingüberspringt PATH-artige Werte und alles mit einer Expansion darin (export GOPATH=$HOME/go); diese kann es statisch nicht auflösen.- Die
path-Zuordnung basiert auf xtrace-Diffs. Die erste Zuweisung, die einen Eintrag enthält, beansprucht ihn, selbst wenn er über eine$PATH-Expansion weitergetragen statt explizit hinzugefügt wurde. - Unter bash meldet Code, der durch
evalausgeführt wird, dieeval-Zeile plus einen Offset; bash hat keinen Marker für eval-Körper wie zsh. - Nicht unterstützte Shells: fish, nu, csh/tcsh, PowerShell.
Von Grund auf schreibgeschützt
envocabulary wird niemals deine Shell-Konfiguration unseten, rmen oder bearbeiten. Ein Notfallwerkzeug sollte nicht das sein, was den Notfall verschlimmert. Wenn du aufräumen möchtest, kopiere die file:line-Verweise und nimm die Änderungen selbst vor. clean gibt nach stdout aus; die Umleitung machst du.