
प्रत्येक शेल पर्यावरण चर को उसकी सटीक फ़ाइल और पंक्ति उत्पत्ति तक ट्रेस करें। macOS, Linux और FreeBSD पर zsh और bash में डेड एंट्रीज़, डुप्लिकेट्स और ऑर्फ़न फ़ाइलों के लिए शेल कॉन्फ़िग्स का ऑडिट करें।
आपके वर्तमान शेल में मौजूद हर वेरिएबल के लिए, वह फ़ाइल और पंक्ति खोजें जिसने उसे सेट किया है — या यह पता लगाएँ कि किस सबसिस्टम (direnv, launchd, टर्मिनल, SSH, system) ने उसे इंजेक्ट किया है। साथ ही कुछ स्टैटिक-फ़ाइल कमांड्स, उस समय के लिए जब आपका शेल कॉन्फ़िग N फ़ाइलों और बैकअप्स में फैल चुका हो और आप समझ नहीं पा रहे हों कि क्या हो रहा है।
मैंने इसे इसलिए बनाया क्योंकि मैं हर कुछ महीनों में वही एक घंटा खो देता था, यह पता लगाने की कोशिश में कि कोई JAVA_HOME या PATH उस जगह क्यों इंगित कर रहा है जहाँ मैंने उम्मीद नहीं की थी। which कमांड्स जानता है, direnv status direnv को जानता है, launchctl getenv launchd को जानता है — इनमें से कोई नहीं बताता कि असली लेखक ~/.zshrc:42 है।
zsh और bash के साथ macOS, Linux और FreeBSD पर काम करता है।
grep -r JAVA_HOME ~ हर उस फ़ाइल को दिखाएगा जो वेरिएबल का उल्लेख करती है, लेकिन आउटपुट से यह स्पष्ट नहीं होता कि वर्तमान शेल में कौन सी असाइनमेंट सक्रिय है:
$ 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]
एक-लाइनर (OS/arch का पता लगाता है, बाइनरी को आपके $PATH पर रखता है, macOS पर Gatekeeper को क्लियर करता है):
curl -fsSL https://raw.githubusercontent.com/sreckoskocilic/envocabulary/main/install.sh | sh
या go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. प्री-बिल्ट बाइनरी और Linux पैकेज (.deb / .rpm / .apk / .pkg.tar.zst) releases page पर उपलब्ध हैं।
लाइव env (आपके चल रहे शेल का निरीक्षण करता है):
scan (डिफ़ॉल्ट) — वर्तमान env में सभी वेरिएबल्स को origin के आधार पर समूहित करके प्रिंट करता हैexplain NAME — दिए गए वेरिएबल के लिए पूर्ण attribution प्रिंट करता हैpath [VARNAME...] — कोलन-सेपरेटेड पाथ वेरिएबल्स के लिए प्रति-एंट्री attribution; --check मृत एंट्रीज़ खोजता हैस्टैटिक फ़ाइलें:
inventory — सभी शेल कॉन्फ़िग फ़ाइलों की सूची बनाता है और प्रकार के अनुसार परिभाषाओं की गिनती करता हैcatalog — सभी कॉन्फ़िग फ़ाइलों को मर्ज करके पूरा शेल कॉन्फ़िगरेशन प्रिंट करता हैdedup — exports, assigns, aliases, functions के लिए क्रॉस-फ़ाइल डुप्लिकेट रिपोर्टdangling — कॉन्फ़िग फ़ाइल एंट्रीज़ को सूचीबद्ध करता है जो अब किसी मान्य लक्ष्य को संदर्भित नहीं करतींlost — orphan/backup कॉन्फ़िग फ़ाइलों के लिए अद्वितीय परिभाषाओं को सूचीबद्ध करता हैreport — संयुक्त ऑडिट: safe-to-delete, review (value-changed dups), dangling, orphaned फ़ाइलें; --html वर्तमान निर्देशिका में टाइमस्टैम्प के साथ एक .html फ़ाइल लिखता हैclean [--full] FILE — हटाई जाने वाली पंक्तियों को सूचीबद्ध करता है; --full के साथ, पूरी साफ़ की गई सामग्री प्रिंट करता हैअन्य:
-V, --version — संस्करण, commit और build date प्रिंट करता हैफ़्लैग्स के लिए envocabulary <cmd> -h।
नीचे दिए गए नमूना आउटपुट में संक्षिप्तता के लिए ~/ का उपयोग किया गया है; टूल हर जगह पूर्ण (absolute) पाथ प्रिंट करता है, सिवाय report के।
dangling कॉन्फ़िग फ़ाइल एंट्रीज़ को सूचीबद्ध करता है जो अब किसी मान्य लक्ष्य को संदर्भित नहीं करतीं — जैसे JAVA_HOME=/opt/jdk-i-uninstalled और 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 दिखाता है कि PATH (या MANPATH, FPATH, आदि) में प्रत्येक एंट्री कहाँ से आई:
$ 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
जिन एंट्रीज़ का मिलान किसी शेल स्टार्टअप असाइनमेंट से नहीं होता, उन्हें inherited के रूप में दिखाया जाता है।
--check उन एंट्रीज़ को फ़िल्टर करता है जिनकी निर्देशिका अब मौजूद नहीं है और उन्हें वापस संपादित करने के लिए कॉन्फ़िग फ़ाइल तक ट्रेस करता है:
$ 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)
मृत एंट्रीज़ मिलने पर 1 कोड के साथ बाहर निकलता है (स्क्रिप्ट्स में उपयोगी)।
export EDITOR=vim VISUAL=vim केवल EDITOR रिकॉर्ड करता है)।dangling PATH-जैसी असाइनमेंट या एक्सपेंशन को हल नहीं करेगा (export GOPATH=$HOME/go)।path attribution xtrace diffs पर आधारित है — पहली असाइनमेंट जो किसी एंट्री को शामिल करती है, उसे अपना लेती है, भले ही वह स्पष्ट रूप से जोड़ने के बजाय $PATH एक्सपेंशन के माध्यम से आगे बढ़ी हो।envocabulary कभी भी आपके शेल कॉन्फ़िग को unset, rm या संपादित नहीं करेगा। एक आपातकालीन टूल को वह चीज़ नहीं बनना चाहिए जो आपातकाल को और बदतर बनाए। यदि आप चीज़ें साफ़ करना चाहते हैं, तो file:line पॉइंटर्स कॉपी करें और संपादन स्वयं करें। clean आउटपुट stdout पर देता है; रीडायरेक्ट आप करते हैं।