direnv
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesedirenv Skill
direnv 使用指南
This skill provides comprehensive guidance for working with direnv, covering installation, configuration, stdlib functions, and best practices for per-project environment management.
本指南提供了direnv的全面使用指导,涵盖安装、配置、标准库函数使用,以及项目专属环境管理的最佳实践。
When to Use This Skill
适用场景
Use this skill when:
- Installing and configuring direnv on macOS or Linux
- Creating or modifying files for projects
.envrc - Setting up per-project environment variables
- Configuring language-specific layouts (Python, Node.js, Ruby, Go, Perl)
- Integrating direnv with Nix or Nix Flakes
- Managing secrets and environment configuration for teams
- Troubleshooting environment loading issues
- Creating custom direnv extensions
在以下场景中使用本指南:
- 在macOS或Linux系统上安装和配置direnv
- 为项目创建或修改文件
.envrc - 配置项目专属环境变量
- 配置特定语言的开发环境(Python、Node.js、Ruby、Go、Perl)
- 将direnv与Nix或Nix Flakes集成
- 为团队管理密钥和环境配置
- 排查环境加载问题
- 创建自定义direnv扩展
Core Concepts
核心概念
What is direnv?
什么是direnv?
direnv is a shell extension that loads and unloads environment variables based on the current directory. When you into a directory with a file, direnv automatically loads the environment. When you leave, it unloads the changes.
cd.envrcdirenv是一款Shell扩展,可根据当前目录加载和卸载环境变量。当你到包含文件的目录时,direnv会自动加载该环境;当你离开该目录时,它会撤销所有环境变更。
cd.envrcSecurity Model
安全模型
direnv uses an allowlist-based security approach:
- New or modified files must be explicitly allowed with
.envrcdirenv allow - Prevents automatic execution of untrusted scripts
- Use to revoke access
direnv deny
direnv采用基于白名单的安全机制:
- 新建或修改后的文件必须通过
.envrc命令手动授权direnv allow - 防止自动执行不受信任的脚本
- 使用命令撤销访问权限
direnv deny
How It Works
工作原理
- Shell hook intercepts directory changes
- Checks for file in current or parent directories
.envrc - If allowed, executes in a bash subshell
.envrc - Captures exported variables and applies them to current shell
- Shell钩子拦截目录切换操作
- 检查当前目录或父目录中是否存在文件
.envrc - 如果已授权,在bash子shell中执行
.envrc - 捕获导出的变量并应用到当前Shell环境
Installation
安装
macOS (Homebrew - Recommended)
macOS(Homebrew - 推荐方式)
bash
brew install direnvbash
brew install direnvLinux
Linux
bash
undefinedbash
undefinedUbuntu/Debian
Ubuntu/Debian
sudo apt install direnv
sudo apt install direnv
Fedora
Fedora
sudo dnf install direnv
sudo dnf install direnv
Arch
Arch
sudo pacman -S direnv
sudo pacman -S direnv
Binary installer (any system)
二进制安装包(适用于所有系统)
curl -sfL https://direnv.net/install.sh | bash
undefinedcurl -sfL https://direnv.net/install.sh | bash
undefinedVerify Installation
验证安装
bash
direnv versionbash
direnv versionShell Configuration
Shell配置
Add the hook to your shell's config file. This is required for direnv to function.
将钩子添加到你的Shell配置文件中。这是direnv正常运行的必要步骤。
Zsh (~/.zshrc)
Zsh (~/.zshrc)
bash
eval "$(direnv hook zsh)"With Oh My Zsh:
bash
plugins=(... direnv)bash
eval "$(direnv hook zsh)"搭配Oh My Zsh使用:
bash
plugins=(... direnv)Bash (~/.bashrc)
Bash (~/.bashrc)
bash
eval "$(direnv hook bash)"Important: Place after rvm, git-prompt, and other prompt-modifying extensions.
bash
eval "$(direnv hook bash)"注意: 将此配置放在rvm、git-prompt等修改提示符的扩展之后。
Fish (~/.config/fish/config.fish)
Fish (~/.config/fish/config.fish)
fish
direnv hook fish | sourcefish
direnv hook fish | sourceAfter Configuration
配置完成后
Restart your shell:
bash
exec $SHELL重启Shell:
bash
exec $SHELL.envrc File Basics
.envrc 文件基础
Creating an .envrc
创建.envrc文件
bash
undefinedbash
undefinedIn your project directory
在你的项目目录中执行
touch .envrc
touch .envrc
Edit with your preferred editor
使用你偏好的编辑器编辑
vim .envrc
undefinedvim .envrc
undefinedBasic Syntax
基础语法
bash
undefinedbash
undefinedExport environment variables
Export environment variables
export NODE_ENV=development
export API_URL=http://localhost:3000
export DATABASE_URL=postgres://localhost/myapp
export NODE_ENV=development
export API_URL=http://localhost:3000
export DATABASE_URL=postgres://localhost/myapp
The export keyword is required for direnv to capture variables
The export keyword is required for direnv to capture variables
undefinedundefinedAllowing the .envrc
授权.envrc文件
bash
undefinedbash
undefinedAllow current directory
授权当前目录
direnv allow
direnv allow
Allow specific path
授权指定路径
direnv allow /path/to/project
direnv allow /path/to/project
Deny/revoke access
拒绝/撤销访问权限
direnv deny
undefineddirenv deny
undefinedStandard Library Functions
标准库函数
direnv includes a powerful stdlib. Always prefer stdlib functions over manual exports.
direnv内置了功能强大的标准库。优先使用标准库函数而非手动导出变量。
PATH Management
PATH管理
bash
undefinedbash
undefinedPrepend to PATH (safer than manual export)
向PATH头部添加路径(比手动导出更安全)
PATH_add bin
PATH_add node_modules/.bin
PATH_add scripts
PATH_add bin
PATH_add node_modules/.bin
PATH_add scripts
Add to arbitrary path-like variable
向任意类路径变量中添加路径
path_add PYTHONPATH lib
path_add LD_LIBRARY_PATH /opt/lib
path_add PYTHONPATH lib
path_add LD_LIBRARY_PATH /opt/lib
Remove from PATH
从PATH中移除路径
PATH_rm "*/.git/bin"
undefinedPATH_rm "*/.git/bin"
undefinedEnvironment File Loading
环境文件加载
bash
undefinedbash
undefinedLoad .env file (current directory)
加载当前目录下的.env文件
dotenv
dotenv
Load specific file
加载指定文件
dotenv .env.local
dotenv .env.local
Load only if exists (no error)
仅在文件存在时加载(无报错)
dotenv_if_exists .env.local
dotenv_if_exists .env.${USER}
dotenv_if_exists .env.local
dotenv_if_exists .env.${USER}
Source another .envrc
加载另一个.envrc文件
source_env ../.envrc
source_env /path/to/.envrc
source_env ../.envrc
source_env /path/to/.envrc
Search upward and source parent .envrc
向上搜索并加载父目录的.envrc文件
source_up
source_up
Source if exists
仅在文件存在时加载
source_env_if_exists .envrc.local
undefinedsource_env_if_exists .envrc.local
undefinedLanguage Layouts
语言环境配置
Node.js:
bash
undefinedNode.js:
bash
undefinedAdds node_modules/.bin to PATH
将node_modules/.bin添加到PATH
layout node
**Python:**
```bashlayout node
**Python:**
```bashCreates virtualenv in .direnv/python-X.X/
在.direnv/python-X.X/目录中创建虚拟环境
layout python
layout python
Use specific Python version
使用特定Python版本
layout python python3.11
layout python python3.11
Shortcut for Python 3
Python 3的快捷方式
layout python3
layout python3
Use Pipenv (reads from Pipfile)
使用Pipenv(读取Pipfile中的配置)
layout pipenv
**Ruby:**
```bashlayout pipenv
**Ruby:**
```bashSets GEM_HOME to project directory
将GEM_HOME设置为项目目录
layout ruby
**Go:**
```bashlayout ruby
**Go:**
```bashModifies GOPATH and adds bin to PATH
修改GOPATH并将bin目录添加到PATH
layout go
**Perl:**
```bashlayout go
**Perl:**
```bashConfigures local::lib environment
配置local::lib环境
layout perl
undefinedlayout perl
undefinedNix Integration
Nix集成
bash
undefinedbash
undefinedLoad nix-shell environment
加载nix-shell环境
use nix
use nix
With specific file
使用指定文件
use nix shell.nix
use nix shell.nix
Load from Nix flake
从Nix flake加载
use flake
use flake
Load specific flake
加载指定flake
use flake "nixpkgs#hello"
use flake ".#devShell"
**For better Nix Flakes support, install nix-direnv:**
```bashuse flake "nixpkgs#hello"
use flake ".#devShell"
**如需更好的Nix Flakes支持,请安装nix-direnv:**
```bashProvides faster, cached use_flake implementation
提供更快的、带缓存的use_flake实现
undefinedundefinedVersion Managers
版本管理器集成
bash
undefinedbash
undefinedrbenv
rbenv
use rbenv
use rbenv
Node.js (with fuzzy version matching)
Node.js(支持模糊版本匹配)
use node 18
use node 18.17.0
use node 18
use node 18.17.0
Reads from .nvmrc if version not specified
未指定版本时读取.nvmrc文件
use node
use node
Julia
Julia
use julia 1.9
undefineduse julia 1.9
undefinedValidation
验证功能
bash
undefinedbash
undefinedRequire environment variables (errors if missing)
检查必填环境变量(缺失则报错)
env_vars_required API_KEY DATABASE_URL SECRET_KEY
env_vars_required API_KEY DATABASE_URL SECRET_KEY
Enforce minimum direnv version
强制要求最低direnv版本
direnv_version 2.32.0
direnv_version 2.32.0
Check git branch
检查Git分支
if on_git_branch main; then
export DEPLOY_ENV=production
fi
if on_git_branch develop; then
export DEPLOY_ENV=staging
fi
undefinedif on_git_branch main; then
export DEPLOY_ENV=production
fi
if on_git_branch develop; then
export DEPLOY_ENV=staging
fi
undefinedFile Watching
文件监听
bash
undefinedbash
undefinedReload when files change
文件变更时自动重载环境
watch_file package.json
watch_file requirements.txt
watch_file .tool-versions
watch_file config/*.yaml
watch_file package.json
watch_file requirements.txt
watch_file .tool-versions
watch_file config/*.yaml
Watch entire directory
监听整个目录
watch_dir config
watch_dir migrations
undefinedwatch_dir config
watch_dir migrations
undefinedUtility Functions
工具函数
bash
undefinedbash
undefinedCheck if command exists
检查命令是否存在
if has docker; then
export DOCKER_HOST=unix:///var/run/docker.sock
fi
if has docker; then
export DOCKER_HOST=unix:///var/run/docker.sock
fi
Expand relative path to absolute
将相对路径转换为绝对路径
expand_path ./bin
expand_path ./bin
Find file searching upward
向上搜索文件
find_up package.json
find_up package.json
Enable strict mode (exit on errors)
启用严格模式(出错即退出)
strict_env
strict_env
Load prefix (configures CPATH, LD_LIBRARY_PATH, etc.)
加载前缀配置(配置CPATH、LD_LIBRARY_PATH等)
load_prefix /usr/local/custom
load_prefix /usr/local/custom
Load remote script with integrity verification
加载远程脚本并验证完整性
source_url https://example.com/script.sh "sha256-HASH..."
undefinedsource_url https://example.com/script.sh "sha256-HASH..."
undefinedBest Practices
最佳实践
Recommended .envrc Template
推荐的.envrc模板
bash
#!/usr/bin/env bashbash
#!/usr/bin/env bash.envrc - Project environment configuration
.envrc - Project environment configuration
Enforce direnv version for team consistency
Enforce direnv version for team consistency
direnv_version 2.32.0
direnv_version 2.32.0
Load .env if exists
Load .env if exists
dotenv_if_exists
dotenv_if_exists
Load local overrides (not committed to git)
Load local overrides (not committed to git)
source_env_if_exists .envrc.local
source_env_if_exists .envrc.local
Language-specific layout
Language-specific layout
layout node # or: layout python3
layout node # or: layout python3
Add project bin directories
Add project bin directories
PATH_add bin
PATH_add scripts
PATH_add bin
PATH_add scripts
Development defaults
Development defaults
export NODE_ENV="${NODE_ENV:-development}"
export LOG_LEVEL="${LOG_LEVEL:-debug}"
export NODE_ENV="${NODE_ENV:-development}"
export LOG_LEVEL="${LOG_LEVEL:-debug}"
Watch for dependency changes
Watch for dependency changes
watch_file package.json
watch_file .nvmrc
undefinedwatch_file package.json
watch_file .nvmrc
undefinedGit Configuration
Git配置
.gitignore:
gitignore
undefined.gitignore:
gitignore
undefinedEnvironment files with secrets
Environment files with secrets
.env
.env.local
.envrc.local
.env
.env.local
.envrc.local
direnv virtualenv/cache
direnv virtualenv/cache
.direnv/
**Commit to repository:**
- `.envrc` (base configuration, no secrets)
- `.env.example` (template for team members).direnv/
**提交到仓库的文件:**
- `.envrc`(基础配置,不含密钥)
- `.env.example`(团队成员使用的模板)Secrets Management
密钥管理
Never commit secrets. Use environment variable fallbacks:
bash
undefined绝对不要提交密钥。 使用环境变量回退机制:
bash
undefined.envrc (committed)
.envrc(已提交)
export DATABASE_URL="${DATABASE_URL:-postgres://localhost/dev}"
export API_KEY="${API_KEY:-}"
export DATABASE_URL="${DATABASE_URL:-postgres://localhost/dev}"
export API_KEY="${API_KEY:-}"
Validate required secrets
Validate required secrets
env_vars_required API_KEY
env_vars_required API_KEY
.envrc.local (gitignored)
.envrc.local(已加入git忽略)
export DATABASE_URL="postgres://user:secret@prod/app"
export API_KEY="actual-secret-key"
undefinedexport DATABASE_URL="postgres://user:secret@prod/app"
export API_KEY="actual-secret-key"
undefinedLayered Configuration
分层配置
bash
undefinedbash
undefined~/projects/.envrc (global dev settings)
~/projects/.envrc(全局开发设置)
export EDITOR=vim
export EDITOR=vim
~/projects/api/.envrc
~/projects/api/.envrc
source_up
export API_PORT=3000
source_up
export API_PORT=3000
~/projects/api/feature/.envrc
~/projects/api/feature/.envrc
source_up
export FEATURE_FLAG=true
undefinedsource_up
export FEATURE_FLAG=true
undefinedProject Structure
项目结构
my-project/
├── .envrc # Base environment (committed)
├── .envrc.local # Local overrides (gitignored)
├── .env # Environment variables (gitignored)
├── .env.example # Template for team (committed)
└── .direnv/ # direnv cache (gitignored)my-project/
├── .envrc # 基础环境配置(已提交)
├── .envrc.local # 本地自定义配置(已忽略)
├── .env # 环境变量文件(已忽略)
├── .env.example # 团队使用的模板(已提交)
└── .direnv/ # direnv虚拟环境/缓存目录(已忽略)Custom Extensions
自定义扩展
Create for custom functions:
~/.config/direnv/direnvrcbash
#!/usr/bin/env bash创建文件来定义自定义函数:
~/.config/direnv/direnvrcbash
#!/usr/bin/env bash~/.config/direnv/direnvrc
~/.config/direnv/direnvrc
Custom function: Use specific Kubernetes context
Custom function: Use specific Kubernetes context
use_kubernetes() {
local context="${1:-default}"
export KUBECONFIG="${HOME}/.kube/config"
kubectl config use-context "$context" >/dev/null 2>&1
log_status "kubernetes context: $context"
}
use_kubernetes() {
local context="${1:-default}"
export KUBECONFIG="${HOME}/.kube/config"
kubectl config use-context "$context" >/dev/null 2>&1
log_status "kubernetes context: $context"
}
Custom function: Load from AWS Secrets Manager
Custom function: Load from AWS Secrets Manager
use_aws_secrets() {
local secret_name="$1"
local region="${2:-us-east-1}"
eval "$(aws secretsmanager get-secret-value
--secret-id "$secret_name"
--region "$region"
--query SecretString
--output text | jq -r 'to_entries | .[] | "export (.key)="(.value)""')" log_status "loaded secrets from: $secret_name" }
--secret-id "$secret_name"
--region "$region"
--query SecretString
--output text | jq -r 'to_entries | .[] | "export (.key)="(.value)""')" log_status "loaded secrets from: $secret_name" }
use_aws_secrets() {
local secret_name="$1"
local region="${2:-us-east-1}"
eval "$(aws secretsmanager get-secret-value
--secret-id "$secret_name"
--region "$region"
--query SecretString
--output text | jq -r 'to_entries | .[] | "export (.key)="(.value)""')" log_status "loaded secrets from: $secret_name" }
--secret-id "$secret_name"
--region "$region"
--query SecretString
--output text | jq -r 'to_entries | .[] | "export (.key)="(.value)""')" log_status "loaded secrets from: $secret_name" }
Custom function: Use asdf versions from .tool-versions
Custom function: Use asdf versions from .tool-versions
use_asdf() {
watch_file .tool-versions
source_env "$(asdf direnv local)"
}
Usage in `.envrc`:
```bash
use kubernetes dev-cluster
use aws_secrets myapp/dev
use asdfuse_asdf() {
watch_file .tool-versions
source_env "$(asdf direnv local)"
}
在`.envrc`中使用:
```bash
use kubernetes dev-cluster
use aws_secrets myapp/dev
use asdfCommands Reference
命令参考
| Command | Description |
|---|---|
| Allow the current .envrc |
| Revoke .envrc access |
| Force reload environment |
| Show current status |
| Dump current environment |
| Open .envrc in editor |
| Show direnv version |
| 命令 | 描述 |
|---|---|
| 授权当前目录的.envrc文件 |
| 撤销.envrc文件的访问权限 |
| 强制重载环境配置 |
| 显示当前状态 |
| 导出当前环境变量 |
| 在编辑器中打开.envrc文件 |
| 显示direnv版本 |
Troubleshooting
故障排查
Environment Not Loading
环境未加载
bash
undefinedbash
undefinedCheck status
检查状态
direnv status
direnv status
Force reload
强制重载
direnv reload
direnv reload
Re-allow .envrc
重新授权.envrc文件
direnv allow
direnv allow
Check if hook is installed
检查钩子是否已安装
echo $DIRENV_DIR
undefinedecho $DIRENV_DIR
undefinedShell Hook Issues
Shell钩子问题
- Verify hook is in shell config file
- Ensure it's at the END of the file
- Restart shell completely:
exec $SHELL - Check for errors:
direnv hook zsh
- 验证钩子已添加到Shell配置文件中
- 确保钩子位于配置文件的末尾
- 完全重启Shell:
exec $SHELL - 检查错误:
direnv hook zsh
Performance Issues
性能问题
bash
undefinedbash
undefinedShow what's being evaluated
显示正在执行的评估内容
direnv show_dump
direnv show_dump
For Nix, use nix-direnv for caching
对于Nix环境,使用nix-direnv来启用缓存
undefinedundefinedDebugging
调试
bash
undefinedbash
undefinedVerbose output
启用详细输出
export DIRENV_LOG_FORMAT='%s'
export DIRENV_LOG_FORMAT='%s'
Show exported variables
显示导出的环境变量
direnv dump | jq
direnv dump | jq
Test .envrc syntax
测试.envrc文件语法
bash -n .envrc
undefinedbash -n .envrc
undefinedIDE Integration
IDE集成
VS Code
VS Code
Install direnv extension for automatic environment loading in integrated terminal.
安装direnv扩展,以在集成终端中自动加载环境。
JetBrains
JetBrains
Install direnv integration plugin.
安装direnv集成插件。
Neovim
Neovim
Use direnv.vim or configure with lua.
使用direnv.vim或通过Lua进行配置。
Common Patterns
常见模式
Development vs Production
开发与生产环境区分
bash
undefinedbash
undefined.envrc
.envrc
export NODE_ENV="${NODE_ENV:-development}"
if [[ "$NODE_ENV" == "development" ]]; then
export DEBUG=true
export LOG_LEVEL=debug
else
export DEBUG=false
export LOG_LEVEL=info
fi
undefinedexport NODE_ENV="${NODE_ENV:-development}"
if [[ "$NODE_ENV" == "development" ]]; then
export DEBUG=true
export LOG_LEVEL=debug
else
export DEBUG=false
export LOG_LEVEL=info
fi
undefinedMulti-Service Projects (Monorepo)
多服务项目(单体仓库)
bash
undefinedbash
undefinedroot/.envrc
root/.envrc
export PROJECT_ROOT="$(pwd)"
export COMPOSE_PROJECT_NAME=myapp
export PROJECT_ROOT="$(pwd)"
export COMPOSE_PROJECT_NAME=myapp
services/api/.envrc
services/api/.envrc
source_up
export SERVICE_NAME=api
export SERVICE_PORT=3000
source_up
export API_PORT=3000
services/web/.envrc
services/web/.envrc
source_up
export SERVICE_NAME=web
export SERVICE_PORT=8080
undefinedsource_up
export SERVICE_PORT=8080
undefinedDocker Integration
Docker集成
bash
undefinedbash
undefined.envrc
.envrc
export COMPOSE_FILE=docker-compose.yml
export COMPOSE_PROJECT_NAME="${PWD##*/}"
if has docker-compose; then
export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}"
fi
export COMPOSE_FILE=docker-compose.yml
export COMPOSE_PROJECT_NAME="${PWD##*/}"
if has docker-compose; then
export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}"
fi
Add Docker bin for containers that install CLI tools
为安装了CLI工具的容器添加Docker bin目录
PATH_add .docker/bin
undefinedPATH_add .docker/bin
undefined