Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
envocabulary — Trace every shell environment variable to its exact file and line origin. Audit shell configs for dead entries, duplicates, and orphaned files across zsh and bash on macOS, Linux, and FreeBSD. | Kitploit
Tools/GitHubGitHub/sreckoskocilic/envocabulary
Scripting & AutomationConfiguration AuditingForensicsDigital ForensicsIncident ResponseLog Analysis
GitHubsreckoskocilic/envocabulary

envocabulary

Trace every shell environment variable to its exact file and line origin. Audit shell configs for dead entries, duplicates, and orphaned files across zsh and bash on macOS, Linux, and FreeBSD.

View Repository
3122 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

envocabulary

CI codecov Go Report Card Release

For every variable in your current shell, find the file and line that set it — or which subsystem (direnv, launchd, terminal, SSH, system) injected it. Plus a few static-file commands for the moment your shell config has sprawled across N files and backups and you've lost the plot.

I built this because I kept losing the same hour every few months tracing why some JAVA_HOME or PATH was pointing somewhere I didn't expect. which knows commands, direnv status knows direnv, launchctl getenv knows launchd — none of them tell you that ~/.zshrc:42 is the actual writer.

Works with zsh and bash on macOS, Linux, and FreeBSD.

The "ah" moment

A grep -r JAVA_HOME ~ will show every file that mentions the variable, but it's not clear from the output which assignment is active in the current shell:

root@kitploit:~
$ 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]

Install

One-liner (detects OS/arch, drops the binary on your $PATH, clears Gatekeeper on macOS):

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

Or go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Pre-built binaries and Linux packages (.deb / .rpm / .apk / .pkg.tar.zst) are on the releases page.

Commands

Live env (introspects your running shell):

  • scan (default) — prints all variables in the current env grouped by origin
  • explain NAME — prints full attribution for provided variable
  • path [VARNAME...] — per-entry attribution for colon-separated path variables; --check finds dead entries

Static files:

  • inventory — lists all shell config files and counts definitions by type
  • catalog — prints entire shell configuration by merging all its config files
  • dedup — cross-file duplicate report for exports, assigns, aliases, functions
  • dangling — lists config file entries that no longer reference a valid target
  • lost — lists definitions unique to orphan/backup config files
  • report — combined audit: safe-to-delete, review (value-changed dups), dangling, orphaned files; --html writes a timestamped .html file into the current directory
  • clean [--full] FILE — lists lines to be stripped; with --full, prints complete cleaned content

Other:

  • -V, --version — print version, commit, and build date

envocabulary <cmd> -h for flags.

Sample output below uses ~/ for brevity; the tool prints absolute paths everywhere except report.

Another example: finding broken references

dangling lists config file entries that no longer reference a valid target — the JAVA_HOME=/opt/jdk-i-uninstalled and source ~/dotfiles/work-old.zsh kind of leftovers:

root@kitploit:~
$ 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)

Another example: tracing PATH entries

path shows where each entry in PATH (or MANPATH, FPATH, etc.) was introduced:

root@kitploit:~
$ 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

Entries not matched to any shell startup assignment are shown as inherited.

--check filters to entries whose directory no longer exists and traces them back to the config file to edit:

root@kitploit:~
$ 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)

Exits 1 when dead entries are found (useful in scripts).

Limits

  • One assignment per line (export EDITOR=vim VISUAL=vim records EDITOR only).
  • dangling will not resolve PATH-like assignments or expansions (export GOPATH=$HOME/go).
  • path attribution is based on xtrace diffs — the first assignment that includes an entry claims it, even if it was carried forward via $PATH expansion rather than explicitly added.
  • Unsupported shells: fish, nu, csh/tcsh, PowerShell.

Read-only by design

envocabulary will never unset, rm, or edit your shell config. An emergency tool shouldn't be the thing that makes the emergency worse. If you want to clean things up, copy the file:line pointers and do the edits yourself. clean outputs to stdout; you do the redirect.

Download Tool