
envocabulary v1.0.4
Отслеживайте каждую переменную окружения оболочки до её точного источника: файла и строки. Проверяйте конфигурации оболочек на наличие мёртвых записей, дубликатов и осиротевших файлов в zsh и bash на macOS, Linux и FreeBSD.
envocabulary
Для каждой переменной в вашей текущей оболочке находит файл и строку, которые её установили, — или определяет, какая подсистема (direnv, launchd, терминал, SSH, система) её внедрила. Плюс несколько команд для статических файлов на тот случай, когда ваш конфиг оболочки расползся по 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]
Установка
Одной строкой (определяет ОС/архитектуру, кладёт бинарник в ваш $PATH, снимает Gatekeeper на macOS):
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) доступны на странице релизов.
Команды
Живое окружение (анализирует вашу работающую оболочку):
scan(по умолчанию) — выводит все переменные текущего окружения, сгруппированные по источникуexplain NAME— выводит полную атрибуцию для указанной переменнойpath [VARNAME...]— по элементная атрибуция для переменных-путей, разделённых двоеточием;--checkнаходит мёртвые записи
Статические файлы:
inventory— перечисляет все конфигурационные файлы оболочки и подсчитывает определения по типамcatalog— выводит всю конфигурацию оболочки, объединяя все её конфигурационные файлыdedup— отчёт о дубликатах между файлами для exports, assigns, aliases, functionsdangling— перечисляет записи конфигурационных файлов, которые больше не ссылаются на валидную цельlost— перечисляет определения, уникальные для осиротевших/резервных конфигурационных файловreport— объединённый аудит: безопасные к удалению, на проверку (дубликаты с изменённым значением), висячие, осиротевшие файлы;--htmlзаписывает файл.htmlс отметкой времени в текущий каталогclean [--full] FILE— выводит строки, которые следует удалить; с--fullпечатает полное очищенное содержимое
Прочее:
-V,--version— вывести версию, коммит и дату сборки
envocabulary <cmd> -h — для получения списка флагов.
В примерах ниже используется ~/ для краткости; инструмент печатает абсолютные пути везде, кроме 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 показывает, где была добавлена каждая запись в 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основана на diff трассировки xtrace — первое присваивание, включающее запись, объявляет её своей, даже если она была перенесена через раскрытие$PATH, а не добавлена явно. - Неподдерживаемые оболочки: fish, nu, csh/tcsh, PowerShell.
Только чтение по замыслу
envocabulary никогда не будет выполнять unset, rm или редактировать ваш конфиг оболочки. Аварийный инструмент не должен усугублять аварию. Если хотите навести порядок, скопируйте указатели file:line и сделайте правки сами. clean выводит результат в stdout; перенаправление делаете вы.