direnv

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

direnv 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
    .envrc
    files for projects
  • 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
cd
into a directory with a
.envrc
file, direnv automatically loads the environment. When you leave, it unloads the changes.
direnv是一款Shell扩展,可根据当前目录加载和卸载环境变量。当你
cd
到包含
.envrc
文件的目录时,direnv会自动加载该环境;当你离开该目录时,它会撤销所有环境变更。

Security Model

安全模型

direnv uses an allowlist-based security approach:
  • New or modified
    .envrc
    files must be explicitly allowed with
    direnv allow
  • Prevents automatic execution of untrusted scripts
  • Use
    direnv deny
    to revoke access
direnv采用基于白名单的安全机制:
  • 新建或修改后的
    .envrc
    文件必须通过
    direnv allow
    命令手动授权
  • 防止自动执行不受信任的脚本
  • 使用
    direnv deny
    命令撤销访问权限

How It Works

工作原理

  1. Shell hook intercepts directory changes
  2. Checks for
    .envrc
    file in current or parent directories
  3. If allowed, executes
    .envrc
    in a bash subshell
  4. Captures exported variables and applies them to current shell
  1. Shell钩子拦截目录切换操作
  2. 检查当前目录或父目录中是否存在
    .envrc
    文件
  3. 如果已授权,在bash子shell中执行
    .envrc
  4. 捕获导出的变量并应用到当前Shell环境

Installation

安装

macOS (Homebrew - Recommended)

macOS(Homebrew - 推荐方式)

bash
brew install direnv
bash
brew install direnv

Linux

Linux

bash
undefined
bash
undefined

Ubuntu/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)

二进制安装包(适用于所有系统)

undefined
undefined

Verify Installation

验证安装

bash
direnv version
bash
direnv version

Shell 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 | source
fish
direnv hook fish | source

After Configuration

配置完成后

Restart your shell:
bash
exec $SHELL
重启Shell:
bash
exec $SHELL

.envrc File Basics

.envrc 文件基础

Creating an .envrc

创建.envrc文件

bash
undefined
bash
undefined

In your project directory

在你的项目目录中执行

touch .envrc
touch .envrc

Edit with your preferred editor

使用你偏好的编辑器编辑

vim .envrc
undefined
vim .envrc
undefined

Basic Syntax

基础语法

bash
undefined
bash
undefined

Export 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

undefined
undefined

Allowing the .envrc

授权.envrc文件

bash
undefined
bash
undefined

Allow current directory

授权当前目录

direnv allow
direnv allow

Allow specific path

授权指定路径

direnv allow /path/to/project
direnv allow /path/to/project

Deny/revoke access

拒绝/撤销访问权限

direnv deny
undefined
direnv deny
undefined

Standard Library Functions

标准库函数

direnv includes a powerful stdlib. Always prefer stdlib functions over manual exports.
direnv内置了功能强大的标准库。优先使用标准库函数而非手动导出变量。

PATH Management

PATH管理

bash
undefined
bash
undefined

Prepend 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"
undefined
PATH_rm "*/.git/bin"
undefined

Environment File Loading

环境文件加载

bash
undefined
bash
undefined

Load .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
undefined
source_env_if_exists .envrc.local
undefined

Language Layouts

语言环境配置

Node.js:
bash
undefined
Node.js:
bash
undefined

Adds node_modules/.bin to PATH

将node_modules/.bin添加到PATH

layout node

**Python:**
```bash
layout node

**Python:**
```bash

Creates 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:**
```bash
layout pipenv

**Ruby:**
```bash

Sets GEM_HOME to project directory

将GEM_HOME设置为项目目录

layout ruby

**Go:**
```bash
layout ruby

**Go:**
```bash

Modifies GOPATH and adds bin to PATH

修改GOPATH并将bin目录添加到PATH

layout go

**Perl:**
```bash
layout go

**Perl:**
```bash

Configures local::lib environment

配置local::lib环境

layout perl
undefined
layout perl
undefined

Nix Integration

Nix集成

bash
undefined
bash
undefined

Load 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:**
```bash
use flake "nixpkgs#hello" use flake ".#devShell"

**如需更好的Nix Flakes支持,请安装nix-direnv:**
```bash

Provides faster, cached use_flake implementation

提供更快的、带缓存的use_flake实现

undefined
undefined

Version Managers

版本管理器集成

bash
undefined
bash
undefined

rbenv

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
undefined
use julia 1.9
undefined

Validation

验证功能

bash
undefined
bash
undefined

Require 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
undefined
if on_git_branch main; then export DEPLOY_ENV=production fi if on_git_branch develop; then export DEPLOY_ENV=staging fi
undefined

File Watching

文件监听

bash
undefined
bash
undefined

Reload 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
undefined
watch_dir config watch_dir migrations
undefined

Utility Functions

工具函数

bash
undefined
bash
undefined

Check 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..."
undefined
source_url https://example.com/script.sh "sha256-HASH..."
undefined

Best Practices

最佳实践

Recommended .envrc Template

推荐的.envrc模板

bash
#!/usr/bin/env bash
bash
#!/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
undefined
watch_file package.json watch_file .nvmrc
undefined

Git Configuration

Git配置

.gitignore:
gitignore
undefined
.gitignore:
gitignore
undefined

Environment 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"
undefined
export DATABASE_URL="postgres://user:secret@prod/app" export API_KEY="actual-secret-key"
undefined

Layered Configuration

分层配置

bash
undefined
bash
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
undefined
source_up export FEATURE_FLAG=true
undefined

Project 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
~/.config/direnv/direnvrc
for custom functions:
bash
#!/usr/bin/env bash
创建
~/.config/direnv/direnvrc
文件来定义自定义函数:
bash
#!/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" }
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" }

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 asdf
use_asdf() { watch_file .tool-versions source_env "$(asdf direnv local)" }

在`.envrc`中使用:
```bash
use kubernetes dev-cluster
use aws_secrets myapp/dev
use asdf

Commands Reference

命令参考

CommandDescription
direnv allow
Allow the current .envrc
direnv deny
Revoke .envrc access
direnv reload
Force reload environment
direnv status
Show current status
direnv dump
Dump current environment
direnv edit
Open .envrc in editor
direnv version
Show direnv version
命令描述
direnv allow
授权当前目录的.envrc文件
direnv deny
撤销.envrc文件的访问权限
direnv reload
强制重载环境配置
direnv status
显示当前状态
direnv dump
导出当前环境变量
direnv edit
在编辑器中打开.envrc文件
direnv version
显示direnv版本

Troubleshooting

故障排查

Environment Not Loading

环境未加载

bash
undefined
bash
undefined

Check 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
undefined
echo $DIRENV_DIR
undefined

Shell Hook Issues

Shell钩子问题

  1. Verify hook is in shell config file
  2. Ensure it's at the END of the file
  3. Restart shell completely:
    exec $SHELL
  4. Check for errors:
    direnv hook zsh
  1. 验证钩子已添加到Shell配置文件中
  2. 确保钩子位于配置文件的末尾
  3. 完全重启Shell:
    exec $SHELL
  4. 检查错误:
    direnv hook zsh

Performance Issues

性能问题

bash
undefined
bash
undefined

Show what's being evaluated

显示正在执行的评估内容

direnv show_dump
direnv show_dump

For Nix, use nix-direnv for caching

对于Nix环境,使用nix-direnv来启用缓存

undefined
undefined

Debugging

调试

bash
undefined
bash
undefined

Verbose 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
undefined
bash -n .envrc
undefined

IDE Integration

IDE集成

VS Code

VS Code

Install direnv extension for automatic environment loading in integrated terminal.
安装direnv扩展,以在集成终端中自动加载环境。

JetBrains

JetBrains

Neovim

Neovim

Use direnv.vim or configure with lua.
使用direnv.vim或通过Lua进行配置。

Common Patterns

常见模式

Development vs Production

开发与生产环境区分

bash
undefined
bash
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
undefined
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
undefined

Multi-Service Projects (Monorepo)

多服务项目(单体仓库)

bash
undefined
bash
undefined

root/.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
undefined
source_up export SERVICE_PORT=8080
undefined

Docker Integration

Docker集成

bash
undefined
bash
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
undefined
PATH_add .docker/bin
undefined

References

参考资料