Volver a actualizaciones
Nuevo releaseSep 16, 2026

envocabulary v1.0.5

Rastrea cada variable de entorno del shell hasta su archivo y línea de origen exactos. Audita las configuraciones del shell en busca de entradas obsoletas, duplicados y archivos huérfanos en zsh y bash en macOS, Linux y FreeBSD.

Compartir

envocabulary

CI codecov Release

Para cada variable en tu shell actual, encuentra el archivo y la línea que la estableció, o qué subsistema (direnv, launchd, terminal, SSH, sistema) la inyectó. Además, algunos comandos para archivos estáticos para el momento en que tu configuración de shell se ha dispersado en N archivos y copias de seguridad y has perdido el hilo.

Construí esto porque perdía la misma hora cada pocos meses rastreando por qué algún JAVA_HOME o PATH apuntaba a un lugar que no esperaba. which conoce comandos, direnv status conoce direnv, launchctl getenv conoce launchd. Ninguno de ellos te dice que ~/.zshrc:42 es el verdadero escritor.

Funciona con zsh y bash en macOS, Linux y FreeBSD. La salida de ejemplo a continuación usa ~/ por brevedad; la herramienta imprime rutas absolutas en todas partes excepto en report.

El momento "ah"

grep -r JAVA_HOME ~ muestra cada archivo que menciona la variable. No te dice qué asignación ganó en el shell en el que estás sentado:

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

Las variables establecidas a través de eval "$(brew shellenv)", eval "$(pyenv init -)" y similares apuntan a la línea eval. El código generado no tiene una línea propia; el eval es lo que puedes abrir en un editor.

Instalación

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

El script detecta el SO y la arquitectura, descarga el archivo de la versión, verifica su suma de comprobación sha256 y verifica la firma de cosign cuando cosign está instalado. Se instala en /usr/local/bin si es escribible, de lo contrario en ~/.local/bin, y advierte si ese directorio no está en tu $PATH. En macOS también elimina el indicador de cuarentena de Gatekeeper.

Opciones: sh -s -- --version v1.0.4 para fijar una versión, --bin-dir DIR para elegir el destino.

O go install github.com/sreckoskocilic/envocabulary/cmd/envocabulary@latest. Ten en cuenta que una compilación con go install informa dev para --version; solo los binarios de la versión llevan la versión, el commit y la fecha de compilación.

Los binarios precompilados y los paquetes de Linux (.deb / .rpm / .apk / .pkg.tar.zst) están en la página de versiones.

Comandos

Entorno en vivo (lee tu shell en ejecución):

  • scan (predeterminado) — imprime todas las variables en el entorno actual agrupadas por origen
  • explain NAME — atribución completa para una variable
  • path [VARNAME...] — atribución por entrada para variables de ruta separadas por dos puntos; --check encuentra entradas muertas

Archivos estáticos:

  • inventory — lista los archivos de configuración del shell en $HOME (los canónicos más variantes de copia de seguridad como .zshrc.bak) y cuenta las definiciones por tipo
  • catalog — imprime esos archivos concatenados en el orden en que el shell los lee
  • dedup — informe de duplicados para exports, assigns, alias, funciones, dentro y entre archivos
  • dangling — lista las entradas de configuración cuyo destino ya no existe; sale con 1 cuando encuentra alguna
  • lost — lista las definiciones que existen solo en archivos huérfanos/de copia de seguridad
  • report — auditoría combinada: seguro de eliminar, revisar (duplicados cuyo valor difiere, más todas las funciones duplicadas), colgantes, archivos huérfanos; --html escribe un archivo .html con marca de tiempo en el directorio actual
  • clean [--full] FILE — lista las líneas de comentario que se eliminarían; con --full, imprime el contenido limpiado

Otros:

  • -V, --version — imprime la versión, el commit y la fecha de compilación

envocabulary <cmd> -h para las opciones.

Códigos de salida: 0 en caso de éxito, 1 en caso de error de tiempo de ejecución o cuando dangling / path --check encuentran algo, 2 en caso de error de uso.

Encontrar referencias rotas

dangling lista las entradas de configuración que ya no apuntan a nada, del tipo JAVA_HOME=/opt/jdk-i-uninstalled y 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)

Rastrear entradas de PATH

path muestra dónde se introdujo cada entrada en PATH (o MANPATH, FPATH, etc.):

$ 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

Las entradas que no coinciden con ninguna asignación de inicio del shell se muestran como inherited. Eso siempre incluye /usr/bin, /bin, /usr/sbin y /sbin: son la semilla desde la que comienza el rastreador, no algo que un archivo añadió.

--check filtra a las entradas cuyo directorio ya no existe y vuelve a resolver el origen contra tus dotfiles y /etc/paths.d, de modo que apunta a la línea que hay que editar:

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

Sale con 1 cuando se encuentran entradas muertas, lo que lo hace utilizable en scripts.

Limitaciones

  • Una asignación por línea: export EDITOR=vim VISUAL=vim registra solo EDITOR.
  • Los comandos estáticos solo miran los dotfiles canónicos en $HOME (.zshenv, .zprofile, .zshrc, .zlogin, .zlogout, .bashrc, .bash_profile, .profile) y sus variantes de estilo .bak/.old. No siguen $ZDOTDIR, ~/.config/zsh, /etc, ni archivos que hagas source.
  • dangling omite valores similares a PATH y cualquier cosa con una expansión (export GOPATH=$HOME/go); no puede resolver esos estáticamente.
  • La atribución de path se basa en diferencias de xtrace. La primera asignación que incluye una entrada la reclama, incluso si fue arrastrada mediante la expansión de $PATH en lugar de añadida explícitamente.
  • Bajo bash, el código ejecutado a través de eval informa la línea eval más un desplazamiento; bash no tiene un marcador para los cuerpos de eval como lo tiene zsh.
  • Shells no compatibles: fish, nu, csh/tcsh, PowerShell.

Solo lectura por diseño

envocabulary nunca hará unset, rm ni editará tu configuración de shell. Una herramienta de emergencia no debería ser lo que empeore la emergencia. Si quieres limpiar cosas, copia los punteros file:line y haz las ediciones tú mismo. clean genera la salida a stdout; tú haces la redirección.

Categorías