Torna agli aggiornamenti
New releaseSep 16, 2026

envocabulary v1.0.5

Traccia ogni variabile d'ambiente della shell fino alla sua esatta origine di file e riga. Controlla le configurazioni della shell per voci morte, duplicati e file orfani attraverso zsh e bash su macOS, Linux e FreeBSD.

Condividi

envocabulary

CI codecov Release

Per ogni variabile nella tua shell corrente, trova il file e la riga che l'ha impostata, oppure quale sottosistema (direnv, launchd, terminale, SSH, sistema) l'ha iniettata. In più, alcuni comandi per file statici per quando la tua configurazione della shell si è sparsa su N file e backup e hai perso il filo.

Ho creato questo strumento perché perdevo la stessa ora ogni pochi mesi a rintracciare perché qualche JAVA_HOME o PATH puntava da qualche parte che non mi aspettavo. which conosce i comandi, direnv status conosce direnv, launchctl getenv conosce launchd. Nessuno di loro ti dice che ~/.zshrc:42 è il vero responsabile.

Funziona con zsh e bash su macOS, Linux e FreeBSD. L'output di esempio qui sotto usa ~/ per brevità; lo strumento stampa percorsi assoluti ovunque tranne che in report.

Il momento "ah"

grep -r JAVA_HOME ~ mostra ogni file che menziona la variabile. Non ti dice quale assegnazione ha vinto nella shell in cui ti trovi:

$ 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]

Le variabili impostate tramite eval "$(brew shellenv)", eval "$(pyenv init -)" e simili puntano alla riga eval. Il codice generato non ha una riga propria; l'eval è ciò che puoi aprire in un editor.

Installazione

curl -fsSL https://raw.githubusercontent.com/sreckoskocilic/envocabulary/main/install.sh | sh

Lo script rileva OS e architettura, scarica l'archivio della release, verifica il suo checksum sha256 e verifica la firma cosign quando cosign è installato. Si installa in /usr/local/bin se scrivibile, altrimenti in ~/.local/bin, e avvisa se quella directory non è nel tuo $PATH. Su macOS cancella anche il flag di quarantena di Gatekeeper.

Opzioni: sh -s -- --version v1.0.4 per fissare una versione, --bin-dir DIR per scegliere la destinazione.

Oppure go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Nota che una build go install riporta dev per --version; solo i binari di release portano versione, commit e data di build.

I binari precompilati e i pacchetti Linux (.deb / .rpm / .apk / .pkg.tar.zst) sono sulla pagina delle release.

Comandi

Env live (legge la tua shell in esecuzione):

  • scan (predefinito) — stampa tutte le variabili nell'env corrente raggruppate per origine
  • explain NAME — attribuzione completa per una variabile
  • path [VARNAME...] — attribuzione per voce per variabili di percorso separate da due punti; --check trova le voci morte

File statici:

  • inventory — elenca i file di configurazione della shell in $HOME (quelli canonici più le varianti di backup come .zshrc.bak) e conta le definizioni per tipo
  • catalog — stampa quei file concatenati nell'ordine in cui la shell li legge
  • dedup — report dei duplicati per export, assegnazioni, alias, funzioni, all'interno e tra i file
  • dangling — elenca le voci di configurazione il cui target non esiste più; esce con 1 quando ne trova
  • lost — elenca le definizioni che esistono solo in file orfani/di backup
  • report — audit combinato: sicuri da eliminare, da rivedere (duplicati con valore diverso, più tutte le funzioni duplicate), dangling, file orfani; --html scrive un file .html con timestamp nella directory corrente
  • clean [--full] FILE — elenca le righe di commento che verrebbero rimosse; con --full, stampa il contenuto pulito

Altro:

  • -V, --version — stampa versione, commit e data di build

envocabulary <cmd> -h per i flag.

Codici di uscita: 0 in caso di successo, 1 in caso di errore a runtime o quando dangling / path --check trovano qualcosa, 2 in caso di errore di utilizzo.

Trovare riferimenti rotti

dangling elenca le voci di configurazione che non puntano più a nulla, il tipo di residui JAVA_HOME=/opt/jdk-i-uninstalled e 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)

Tracciare le voci di PATH

path mostra dove è stata introdotta ogni voce in PATH (o MANPATH, FPATH, ecc.):

$ 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

Le voci non corrispondenti a nessuna assegnazione di avvio della shell appaiono come inherited. Questo include sempre /usr/bin, /bin, /usr/sbin e /sbin: sono il seme da cui parte il tracer, non qualcosa aggiunto da un file.

--check filtra alle voci la cui directory non esiste più e ri-risolve la sorgente rispetto ai tuoi dotfile e a /etc/paths.d, così punta alla riga da modificare:

$ 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)

Esce con 1 quando trova voci morte, il che lo rende utilizzabile negli script.

Limiti

  • Un'assegnazione per riga: export EDITOR=vim VISUAL=vim registra solo EDITOR.
  • I comandi statici guardano solo i dotfile canonici in $HOME (.zshenv, .zprofile, .zshrc, .zlogin, .zlogout, .bashrc, .bash_profile, .profile) e le loro varianti in stile .bak/.old. Non seguono $ZDOTDIR, ~/.config/zsh, /etc o i file che fai source.
  • dangling salta i valori simili a PATH e qualsiasi cosa contenga un'espansione (export GOPATH=$HOME/go); non può risolverli staticamente.
  • L'attribuzione di path si basa sui diff di xtrace. La prima assegnazione che include una voce la rivendica, anche se è stata portata avanti tramite espansione di $PATH invece che aggiunta esplicitamente.
  • Sotto bash, il codice eseguito tramite eval riporta la riga eval più un offset; bash non ha un marcatore per i corpi di eval come ce l'ha zsh.
  • Shell non supportate: fish, nu, csh/tcsh, PowerShell.

Di sola lettura per design

envocabulary non farà mai unset, rm o modificherà la tua configurazione della shell. Uno strumento di emergenza non dovrebbe essere ciò che peggiora l'emergenza. Se vuoi fare pulizia, copia i puntatori file:line e fai le modifiche da solo. clean scrive su stdout; il redirect lo fai tu.

Categorie