Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • shell

  • tool

    • mac 百问记录
    • mac tool
    • tmux
    • c tool
    • platform
    • dev tool
    • java tool
    • IDEA
    • vscode
    • Docker 使用指南
    • unbuntuOnWindows
    • oh-my-zsh
    • github
    • lldb
    • ripgrep 高性能文本搜索工具使用指南
    • appium
    • mvn
    • ffmpeg
    • gradle
    • git 使用指南
    • jenv
    • php-fpm
    • raycast
    • VisiData 终极生存指南(vd)
    • yq
    • direnv
      • 1. 什么是 direnv
      • 2. 安装
      • 3. 快速开始
        • 3.1 配置 shell hook
        • 3.2 创建 .envrc
        • 3.3 批准 .envrc
      • 4. 常用命令
      • 5. 常用场景
        • 5.1 Node.js 版本管理
        • 5.2 Python 虚拟环境
        • 5.3 项目环境变量
        • 5.4 扩展 PATH
        • 5.5 加载 .env 文件
        • 5.6 多环境切换
      • 6. 标准库(stdlib)
        • 6.1 路径管理
        • 6.2 环境变量
        • 6.3 语言版本管理
        • 6.4 虚拟环境
        • 6.5 其他实用函数
      • 7. 安全机制
        • 7.1 为什么需要 allow
        • 7.2 查看已批准的目录
        • 7.3 全局白名单
      • 8. 与其他工具集成
        • 8.1 与 nvm 集成
        • 8.2 与 pyenv 集成
        • 8.3 与 asdf 集成
        • 8.4 与 .env 文件集成
        • 8.5 与 VS Code 集成
      • 9. 常见问题
        • 9.1 修改 .envrc 后不生效
        • 9.2 进入目录没有反应
        • 9.3 环境变量没有卸载
        • 9.4 如何调试 .envrc
        • 9.5 .envrc 应该提交到 git 吗
      • 10. 实用技巧
        • 10.1 全局配置
        • 10.2 监视文件变化
        • 10.3 条件加载
        • 10.4 项目根目录向上查找
      • 参考链接
    • Vim 编辑器入门指南
    • jadx
    • excalidraw 入门指南
    • whimsical 入门指南
    • mermaid 入门指南
  • client

  • 网络

  • compute_base

  • blog

  • growth

  • java

  • C&C++

  • ai

  • secure

  • cms

  • english

  • 生活

  • 金融学

  • more

  • other
  • tool
Jacky
2026-09-09
目录

direnv

direnv 是一个 shell 环境管理工具,能够在进入目录时自动加载项目特定的环境变量,离开目录时自动卸载。支持 bash、zsh、fish、tcsh 等多种 shell。

# 1. 什么是 direnv

每个项目可能需要不同的环境变量(Node 版本、Python 虚拟环境、API Key、PATH 扩展等)。direnv 通过在项目根目录放置 .envrc 文件,实现:

  • 进入目录:自动加载 .envrc 中定义的环境变量
  • 离开目录:自动恢复之前的环境,不污染全局 shell
  • 安全机制:.envrc 修改后需手动 direnv allow 批准,防止恶意代码自动执行

# 2. 安装

# macOS
brew install direnv

# Ubuntu/Debian
sudo apt-get install direnv

# Arch Linux
sudo pacman -S direnv
1
2
3
4
5
6
7
8

# 3. 快速开始

# 3.1 配置 shell hook

在 shell 配置文件中添加 hook(根据使用的 shell 选择):

zsh(~/.zshrc)

eval "$(direnv hook zsh)"
1

bash(~/.bashrc 或 ~/.bash_profile)

eval "$(direnv hook bash)"
1

fish(~/.config/fish/config.fish)

direnv hook fish | source
1

配置后重启终端或 source ~/.zshrc 生效。

# 3.2 创建 .envrc

在项目根目录创建 .envrc 文件:

# 项目根目录
cd my-project

# 创建 .envrc
echo 'export NODE_ENV=development' > .envrc
1
2
3
4
5

此时会看到提示:

direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
1

# 3.3 批准 .envrc

direnv allow
1

批准后,进入目录时自动加载环境变量:

direnv: export +NODE_ENV
1

离开目录时自动卸载:

direnv: export -NODE_ENV
1

# 4. 常用命令

命令 说明
direnv allow [路径] 批准当前目录(或指定目录)的 .envrc
direnv deny [路径] 拒绝/撤销 .envrc 的批准
direnv reload 重新加载当前目录的 .envrc
direnv status 查看 direnv 状态(哪些目录已批准、当前加载情况)
direnv edit [路径] 编辑 .envrc(保存后自动 allow)
direnv exec <目录> <命令> 在指定目录的环境下执行命令(不切换目录)
direnv export <shell> 导出当前目录的环境变量(用于调试)
direnv version 查看版本

# 5. 常用场景

# 5.1 Node.js 版本管理

配合 nvm 使用:

# .envrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
nvm use v18.20.7
1
2
3
4

或使用标准库(更简洁):

# .envrc
use node 18.20.7
1
2

# 5.2 Python 虚拟环境

# .envrc
# 自动激活 venv(如果存在)
layout python-venv

# 或指定虚拟环境目录
layout python-venv .venv
1
2
3
4
5
6

layout python-venv 会自动:

  • 创建虚拟环境(如果不存在)
  • 激活虚拟环境
  • 离开目录时自动 deactivate

# 5.3 项目环境变量

# .envrc
export API_KEY="your-api-key-here"
export DATABASE_URL="postgres://localhost:5432/mydb"
export DEBUG=true
1
2
3
4

# 5.4 扩展 PATH

将项目本地的 bin/ 目录加入 PATH:

# .envrc
PATH_add bin
1
2

或使用标准库:

# .envrc
path_add bin
1
2

# 5.5 加载 .env 文件

如果项目使用 .env 文件管理环境变量:

# .envrc
dotenv
1
2

dotenv 会自动加载当前目录的 .env 文件。也可以指定文件名:

dotenv .env.development
1

# 5.6 多环境切换

# .envrc
# 根据当前 git 分支加载不同环境
if [ "$(git branch --show-current)" = "main" ]; then
  export NODE_ENV=production
else
  export NODE_ENV=development
fi
1
2
3
4
5
6
7

# 6. 标准库(stdlib)

direnv 内置了一组实用函数,可在 .envrc 中直接使用:

# 6.1 路径管理

函数 说明
path_add <路径> 将路径加入 PATH(去重)
PATH_add <路径> 同上(兼容旧写法)
path_rm <路径> 从 PATH 中移除
manpath_add <路径> 将路径加入 MANPATH

# 6.2 环境变量

函数 说明
export <变量>=<值> 设置环境变量(标准 shell 语法)
unset <变量> 取消环境变量
set -a / set +a 自动 export 所有变量

# 6.3 语言版本管理

函数 说明
use node <版本> 使用 nvm 切换 Node 版本
use ruby <版本> 使用 rbenv/chruby 切换 Ruby 版本
use python <版本> 使用 pyenv 切换 Python 版本
use go <版本> 切换 Go 版本
use java <版本> 切换 Java 版本
use rust <版本> 切换 Rust 版本

# 6.4 虚拟环境

函数 说明
layout python 创建并激活 Python 虚拟环境(virtualenv)
layout python-venv 创建并激活 Python venv(Python 3.3+ 内置)
layout node 初始化 Node 项目环境
layout ruby 初始化 Ruby 项目环境
layout go 初始化 Go 项目环境(设置 GOPATH)

# 6.5 其他实用函数

函数 说明
dotenv [文件] 加载 .env 文件
source_env <文件> 加载另一个 envrc 文件
source_env_if_exists <文件> 如果文件存在则加载
watch_file <文件> 监视文件变化,变化时自动 reload
has <命令> 检查命令是否存在(返回 0/1)
join_args <args> 将参数拼接为字符串

# 7. 安全机制

direnv 的安全设计是其核心特性之一:

# 7.1 为什么需要 allow

.envrc 是一个可执行的 shell 脚本,如果自动加载可能导致恶意代码执行(例如克隆一个包含恶意 .envrc 的项目后,进入目录就自动执行)。

因此 direnv 要求:

  • 首次进入目录:必须手动 direnv allow
  • .envrc 修改后:之前的 allow 失效,需要重新 direnv allow
  • 可以随时 direnv deny 撤销批准

# 7.2 查看已批准的目录

direnv status
1

输出示例:

direnv exec path /usr/local/bin/direnv
DIRENV_CONFIG /Users/xxx/.config/direnv
bash_path: /bin/bash
...

Loaded RC path: /path/to/project/.envrc
Allowed RC path: /path/to/project/.envrc
1
2
3
4
5
6
7

# 7.3 全局白名单

如果信任某个目录下的所有项目,可以在全局配置中设置白名单:

# ~/.config/direnv/direnv.toml
[whitelist]
prefix = ["/path/to/trusted/projects"]
1
2
3

# 8. 与其他工具集成

# 8.1 与 nvm 集成

# .envrc
use node 18.20.7
1
2

use node 会自动查找 nvm 并切换版本。如果 nvm 未安装,会提示错误。

# 8.2 与 pyenv 集成

# .envrc
use python 3.11.4
layout python-venv
1
2
3

# 8.3 与 asdf 集成

# .envrc
use asdf
1
2

use asdf 会自动读取项目根目录的 .tool-versions 文件。

# 8.4 与 .env 文件集成

很多项目(尤其是 Node.js)使用 .env 文件管理环境变量:

# .envrc
dotenv
1
2

.env 文件示例:

DATABASE_URL=postgres://localhost:5432/mydb
API_KEY=secret-key
DEBUG=true
1
2
3

# 8.5 与 VS Code 集成

在 VS Code 中,direnv 加载的环境变量不会自动传递给 VS Code 的终端和调试器。可以安装 direnv 扩展,或在 .vscode/settings.json 中配置:

{
  "terminal.integrated.env.osx": {
    "DIRENV_LOG_FORMAT": ""
  }
}
1
2
3
4
5

# 9. 常见问题

# 9.1 修改 .envrc 后不生效

修改 .envrc 后,direnv 会自动检测到变化并提示重新 allow:

direnv: error .envrc has changed. Run `direnv allow` to approve its content.
1

运行 direnv allow 或 direnv reload 即可。

也可以使用 direnv edit 编辑,保存后自动 allow:

direnv edit
1

# 9.2 进入目录没有反应

检查:

  1. shell hook 是否配置:eval "$(direnv hook zsh)"
  2. .envrc 是否存在于当前目录
  3. 是否已经 direnv allow
  4. direnv 版本是否过旧:direnv version

# 9.3 环境变量没有卸载

direnv 通过记录进入目录前的环境状态,在离开时恢复。如果环境变量没有正确卸载,可能是因为 .envrc 中使用了不规范的方式修改变量。

正确做法:使用 direnv 标准库函数

# 正确
path_add bin
export MY_VAR=value

# 不推荐(可能导致卸载异常)
export PATH="$PWD/bin:$PATH"
1
2
3
4
5
6

# 9.4 如何调试 .envrc

# 查看 direnv 会执行什么
direnv export bash

# 在指定目录环境下执行命令
direnv exec /path/to/project env

# 详细日志
DIRENV_DEBUG=1 direnv reload
1
2
3
4
5
6
7
8

# 9.5 .envrc 应该提交到 git 吗

取决于内容:

  • 如果 .envrc 只包含公开的环境配置(如 Node 版本、PATH 扩展),可以提交
  • 如果包含敏感信息(API Key、密码),不要提交,应加入 .gitignore,并提供 .envrc.example 模板

推荐做法:

# .gitignore
.envrc
.env
.env.local

# 提交模板
.envrc.example
1
2
3
4
5
6
7

# 10. 实用技巧

# 10.1 全局配置

创建全局 direnv 配置,所有项目共享:

# ~/.config/direnv/direnvrc
# 这里定义的函数在所有 .envrc 中可用

my_custom_function() {
  echo "Hello from global direnv config"
}
1
2
3
4
5
6

# 10.2 监视文件变化

如果 .envrc 依赖其他文件(如 .nvmrc、.tool-versions),可以监视这些文件:

# .envrc
watch_file .nvmrc
use node $(cat .nvmrc)
1
2
3

当 .nvmrc 变化时,direnv 会自动 reload。

# 10.3 条件加载

# .envrc
# 只在 macOS 上设置某些变量
if [ "$(uname)" = "Darwin" ]; then
  export MACOS_SPECIFIC_VAR=value
fi

# 只在命令存在时加载
if has docker; then
  export DOCKER_BUILDKIT=1
fi
1
2
3
4
5
6
7
8
9
10

# 10.4 项目根目录向上查找

direnv 会从当前目录向上查找 .envrc,直到找到为止。这意味着在项目的子目录中也能正确加载环境变量。

如果子目录有自己的 .envrc,会覆盖父目录的配置。

# 参考链接

  • direnv 官方网站 (opens new window)
  • direnv GitHub (opens new window)
  • direnv 标准库文档 (opens new window)
  • direnv 配置文档 (opens new window)
#direnv#Shell#tool
上次更新: 2026/09/10, 14:32:04
yq
Vim 编辑器入门指南

← yq Vim 编辑器入门指南→

最近更新
01
nvim
09-09
02
wget
09-09
03
watch
09-09
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式