العودة إلى التحديثات
New releaseSep 16, 2026

envocabulary v1.0.5

تتبع كل متغير بيئة في الصدفة إلى ملفه وسطر مصدره بدقة. دقق في إعدادات الصدفة بحثًا عن إدخالات ميتة، ومكررات، وملفات يتيمة عبر zsh وbash على macOS وLinux وFreeBSD.

مشاركة

envocabulary

CI codecov Release

لكل متغير في الصدفة الحالية لديك، ابحث عن الملف والسطر الذي قام بتعيينه، أو أي نظام فرعي (direnv، launchd، terminal، SSH، system) قام بحقنه. بالإضافة إلى بعض أوامر الملفات الثابتة للحظة التي تنتشر فيها إعدادات الصدفة عبر N من الملفات والنسخ الاحتياطية وتفقد السيطرة.

بنيت هذا لأنني كنت أفقد نفس الساعة كل بضعة أشهر في تتبع سبب إشارة بعض JAVA_HOME أو PATH إلى مكان لم أتوقعه. which يعرف الأوامر، direnv status يعرف direnv، launchctl getenv يعرف launchd. لا أحد منهم يخبرك أن ~/.zshrc:42 هو الكاتب الفعلي.

يعمل مع zsh و bash على macOS و Linux و FreeBSD. المخرجات النموذجية أدناه تستخدم ~/ للإيجاز؛ الأداة تطبع المسارات المطلقة في كل مكان باستثناء report.

لحظة "آها"

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]

المتغيرات المعينة عبر eval "$(brew shellenv)" و eval "$(pyenv init -)" وما شابه تشير إلى سطر eval. الكود المُولَّد ليس له سطر خاص به؛ eval هو ما يمكنك فتحه في محرر.

التثبيت

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

يكتشف السكربت نظام التشغيل والمعمارية، ويحمّل أرشيف الإصدار، ويتحقق من مجموع التحقق sha256 الخاص به، ويتحقق من توقيع cosign عند تثبيت cosign. يثبّت في /usr/local/bin إذا كان قابلاً للكتابة، وإلا في ~/.local/bin، ويحذّر إذا لم يكن ذلك الدليل على $PATH الخاص بك. على macOS يقوم أيضاً بمسح علامة الحجر الصحي الخاصة بـ Gatekeeper.

الخيارات: sh -s -- --version v1.0.4 لتثبيت إصدار معين، --bin-dir DIR لاختيار الوجهة.

أو go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. لاحظ أن بناء go install يُبلّغ عن dev لـ --version؛ فقط ثنائيات الإصدار تحمل الإصدار والالتزام وتاريخ البناء.

الثنائيات الجاهزة وحزم Linux (.deb / .rpm / .apk / .pkg.tar.zst) موجودة على صفحة الإصدارات.

الأوامر

البيئة الحية (تقرأ الصدفة قيد التشغيل):

  • scan (افتراضي) — يطبع جميع المتغيرات في البيئة الحالية مجمّعة حسب الأصل
  • explain NAME — الإسناد الكامل لمتغير واحد
  • path [VARNAME...] — إسناد لكل مدخل لمتغيرات المسار المفصولة بنقطتين؛ --check يجد المدخلات الميتة

الملفات الثابتة:

  • inventory — يسرد ملفات إعدادات الصدفة في $HOME (الملفات الأساسية بالإضافة إلى النسخ الاحتياطية مثل .zshrc.bak) ويحصي التعريفات حسب النوع
  • catalog — يطبع تلك الملفات مدمجة بالترتيب الذي تقرأها به الصدفة
  • dedup — تقرير التكرارات لـ exports و assigns و aliases و functions، داخل الملفات وعبرها
  • dangling — يسرد مدخلات الإعدادات التي لم يعد هدفها موجوداً؛ يخرج بـ 1 عند العثور على أي منها
  • lost — يسرد التعريفات الموجودة فقط في الملفات اليتيمة/الاحتياطية
  • report — تدقيق مدمج: آمن للحذف، مراجعة (التكرارات التي تختلف قيمتها، بالإضافة إلى جميع الدوال المكررة)، dangling، الملفات اليتيمة؛ --html يكتب ملف .html بطابع زمني في الدليل الحالي
  • clean [--full] FILE — يسرد أسطر التعليقات التي سيتم إزالتها؛ مع --full، يطبع المحتوى المنظّف

أخرى:

  • -V، --version — طباعة الإصدار والالتزام وتاريخ البناء

envocabulary <cmd> -h للأعلام.

رموز الخروج: 0 عند النجاح، 1 عند خطأ وقت التشغيل أو عندما يجد dangling / path --check شيئاً، 2 عند خطأ في الاستخدام.

إيجاد المراجع المعطوبة

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 يُظهر أين تم إدخال كل مدخل في PATH (أو MANPATH، FPATH، إلخ):

$ 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

المدخلات غير المطابقة لأي إسناد بدء تشغيل الصدفة تظهر كـ inherited. يشمل ذلك دائماً /usr/bin و /bin و /usr/sbin و /sbin: فهي البذرة التي يبدأ منها المتتبع، وليست شيئاً أضافه ملف.

--check يرشّح إلى المدخلات التي لم يعد دليلها موجوداً ويعيد تحليل المصدر مقابل ملفات dotfiles و /etc/paths.d، بحيث يشير إلى السطر الذي يجب تعديله:

$ 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 فقط.
  • الأوامر الثابتة تنظر فقط إلى ملفات dotfiles الأساسية في $HOME (.zshenv، .zprofile، .zshrc، .zlogin، .zlogout، .bashrc، .bash_profile، .profile) ومتغيراتها من نوع .bak/.old. لا تتبع $ZDOTDIR أو ~/.config/zsh أو /etc أو الملفات التي تقوم بـ source لها.
  • dangling يتخطى القيم الشبيهة بـ PATH وأي شيء يحتوي على توسيع (export GOPATH=$HOME/go)؛ لا يمكنه تحليل تلك بشكل ثابت.
  • إسناد path يعتمد على فروقات xtrace. أول إسناد يتضمن مدخلاً يطالب به، حتى لو تم نقله عبر توسيع $PATH بدلاً من إضافته صراحة.
  • تحت bash، الكود الذي يعمل عبر eval يُبلّغ عن سطر eval بالإضافة إلى إزاحة؛ bash ليس لديه علامة لأجسام eval كما هو الحال في zsh.
  • الصدفات غير المدعومة: fish، nu، csh/tcsh، PowerShell.

للقراءة فقط بحكم التصميم

لن يقوم envocabulary أبداً بـ unset أو rm أو تعديل إعدادات الصدفة الخاصة بك. أداة الطوارئ لا ينبغي أن تكون الشيء الذي يزيد الطوارئ سوءاً. إذا أردت تنظيف الأمور، انسخ مؤشرات file:line وقم بالتعديلات بنفسك. clean يُخرج إلى stdout؛ أنت تقوم بإعادة التوجيه.

الفئات