dotenv 用法速查表 - .env 环境变量配置与多环境加载顺序

几乎每个 Node/Python/前端项目都要写 .env,但最容易栽的坑是等号两侧留空格、值里的 # 被当注释、密钥误提交进仓库。这份速查覆盖 5 组:变量定义、在 Shell/Node/Python 里如何读取、dotenv 的加载写法、多环境文件(.env/.env.local/.env.production)的组织,以及一组安全陷阱提醒。写完对照检查格式,部署前确认密钥没有被提交。读完后你能规范组织环境变量,并规避最常见的数据泄漏问题。

配置格式·共 24 条命令·最后更新 2026-08-02
envdotenv环境变量config.env

典型使用场景

面向需要把配置与密钥从代码里分离出来的开发者:本地开发用 .env,生产用真实环境变量,团队间用 .env.example 对齐字段名。本表覆盖变量定义与读取、各语言/Shell 的访问方式、dotenv 加载、多环境文件约定与四类安全陷阱。核心判断标准只有一条——真实密钥永远不进版本库。

变量定义 Definition 6

KEY=value
定义变量(等号两侧不要有空格)
KEY="value with space"
含空格或特殊字符需加引号
KEY='literal $NOT_EXPANDED'
单引号内不做变量展开
KEY=${OTHER}_suffix
双引号内可引用其他变量
# comment
井号开头为注释行
export KEY=value
设置并导出为环境变量

引用与读取 Reading 5

echo $KEY
Shell 中读取变量(Linux/macOS)
echo %KEY%
Windows cmd 读取变量
$env:KEY
PowerShell 读取变量
process.env.KEY
Node.js 读取
os.getenv("KEY")
Python 读取

dotenv 用法 4

require('dotenv').config()
Node 加载 .env 到 process.env
import 'dotenv/config'
ESM 写法加载 .env
dotenv.config({ path: '.env.local' })
指定自定义文件路径
python-dotenv load_dotenv()
Python 加载 .env

多环境文件 Multi-env 5

.env
默认环境(勿提交到 git)
.env.local
本地覆盖(优先级更高)
.env.development
开发环境
.env.production
生产环境
.env.example
示例模板,可提交,不含真实密钥

安全陷阱 Security FAQ 4

不要提交密钥
把 .env 加入 .gitignore,用 .env.example 提供模板
区分大小写
KEY 与 key 是不同变量
类型转换
所有值都是字符串,数字需自行 parseInt/Number()
换行需转义
多行值用引号包裹或使用

参数矩阵

参数作用示例
KEY=value定义变量,等号两侧不可有空格KEY=value
KEY="a b"含空格或特殊字符需加引号KEY="value with space"
KEY='$RAW'单引号内不做变量展开KEY='literal $NOT_EXPANDED'
export KEY=value设置并导出为环境变量,供子进程读取export DATABASE_URL=postgres://...
$KEY / %KEY% / $env:KEY三平台读取语法:Shell / cmd / PowerShellecho $KEY
dotenv.config()Node 把 .env 载入 process.envrequire('dotenv').config()
import 'dotenv/config'ESM 写法加载 .envimport 'dotenv/config'
.env.local本地覆盖,优先级高于 .envdotenv.config({ path: '.env.local' })
.env.<mode>按环境分文件:development / production.env.production
.env.example示例模板,可提交,不含真实密钥cp .env .env.example
os.getenv("KEY")Python 读取;未设置时返回 Noneos.getenv("DATABASE_URL")
process.env.KEYNode 读取;未设置时为 undefinedprocess.env.PORT

易错点与避坑指南

现象变量明明在文件里写了,读取却是空值。

原因等号两侧加了空格(KEY = value 被解析为执行命令 KEY),或用了未导出的普通变量。

处置写成 KEY=value 不带空格,并加 export 让子进程可见。

现象密钥提交进了 Git,历史里还能查到,即使现在删除文件也不安全。

原因.env 未加入 .gitignore,或已追踪后补的忽略规则不生效。

处置立即轮换密钥(改 ignore 无法撤回已泄露内容);git rm --cached .env 移出索引,并补 .gitignore。

现象跨平台脚本在 Windows 上运行失败,Linux 正常。

原因Shell 用 $KEY 读取,而 cmd 需要 %KEY%。

处置跨平台脚本避免直接读环境变量,或分别处理两套语法。

现象读出来的是字符串 "8080" 而不是数字,直接比较大小报类型错误。

原因环境变量的值一律是字符串,没有类型。

处置显式转换:Number(process.env.PORT) 或 parseInt(..., 10)。

现象多行值(如私钥)写入 .env 后只能读到第一行。

原因换行符未转义,解析在第一行就截断。

处置用引号包裹并把真实换行写成 \n,或改用 base64 / 密钥管理服务。

现象本地改了 .env.local 但应用读到的还是旧值。

原因dotenv 默认不覆盖已存在的 process.env 值。

处置用 dotenv.config({ override: true }),或确认加载顺序符合预期。

排障路径

  1. 1确认变量确实存在于当前 shell

    echo $KEY

    没输出说明没 export 或没加载 .env;用 set | grep KEY 也可。

  2. 2从文件临时加载到当前会话

    set -a && source .env && set +a

    set -a 让 source 定义的变量自动导出,+a 恢复;仅当前 shell 有效。

  3. 3确认 Node 侧是否真的读到了

    node -e "console.log(process.env.KEY)"

    绕过应用直接问运行时,能区分是加载失败还是代码没读对字段。

  4. 4生成不含密钥的提交模板

    sed -E "s/=.*/=/" .env > .env.example

    保留 KEY 名清空值;确认 .env 已在 .gitignore 中。

  5. 5排查密钥是否已泄露进版本库

    git log -S "SECRET_VALUE" --oneline

    能命中就说明历史里存在,必须轮换密钥,改 .gitignore 只防未来。

命令示例

定义变量并导出给子进程

export DATABASE_URL=postgres://localhost:5432/app

等号两侧不能有空格;只 set 不 export 的话子进程读不到这个值。

从指定路径加载 .env 文件

dotenv.config({ path: '.env.local' })

不传 path 时默认读项目根目录的 .env;传了就只读指定文件,不会自动合并。

三个平台各自的读取语法

echo $KEY # Linux/macOS echo %KEY% # Windows cmd $env:KEY # PowerShell

同一份配置要在不同平台跑时,读取语法本身就不同,脚本不能假定只有一种。

Python 中加载并读取变量

from dotenv import load_dotenv load_dotenv() os.getenv("API_HOST")

变量不存在时返回 None,判断配置是否加载成功要先处理这个 None 分支。

常见坑与注意事项

  • 把 .env 加入 .gitignore,真实密钥永远不进版本库,提交 .env.example 作为字段模板。
  • 等号两侧不要留空格,KEY = value 不会完成赋值,变量名保持全大写下划线风格最不易出错。
  • 所有值都是字符串,数字和布尔必须自行转换,"false" 在 JavaScript 里是 truthy,直接判断会得到相反结果。
  • 变量名区分大小写,KEY 与 key 在 Linux/macOS 上是两个变量,排查空值时先确认大小写完全一致。
  • 多行内容(私钥、证书)必须用引号整体包裹或写成显式换行转义,否则只能读到第一行。

提示

  • 等号两侧不要留空格(KEY=value 正确,KEY = value 错误)。
  • 把 .env 加入 .gitignore,密钥改用 .env.example 模板提交。
  • 所有值都是字符串,数字需用 Number()/parseInt() 转换。
  • 多行值用引号包裹或 \n 表示换行。

常见问题

变量明明写在 .env 里,读出来却是空的?

按顺序排三种最常见原因:一是等号两侧留了空格,KEY = value 会被当成一个整体而不是赋值;二是只定义了但没有 export,子进程读不到;三是变量名大小写不一致,KEY 和 key 是两个完全不同的变量,Linux 上是区分大小写的。

为什么端口号读出来是字符串,比较大小时报类型错误?

.env 里的值一律按字符串处理,不存在类型标注,PORT=8080 拿到的就是 "8080" 这段文本。直接拿它和数字比较或做算术就会在运行时报错,必须自己转换:Node 里用 Number(process.env.PORT),Python 里用 int(os.getenv("PORT"))。布尔值同理,"false" 这个字符串在 JavaScript 里是 truthy。

私钥那种多行值写进 .env 后只读到第一行?

.env 按行解析,裸换行会把一行内容截断成两行,第二行会被当成新的变量或直接忽略。多行值要用引号整体包裹,或者用显式的换行转义序列表示,保证整个值仍处在同一行里。

.env 和 .env.local 同时存在时哪个生效?

.env.local 优先级更高,它扮演本地覆盖的角色,适合放只有你本机需要的值,比如指向本地数据库的连接串。基础配置放 .env,需要分环境的用 .env.development 和 .env.production,给团队对齐字段名的是不含真实密钥的 .env.example。

Node 和 Python 分别怎么从 .env 里取值?

Node 先 require('dotenv').config() 把文件载入 process.env,之后用 process.env.KEY 读;ESM 环境改用 import 'dotenv/config' 这一行侧效应写法。Python 用 python-dotenv 的 load_dotenv() 载入,读取走 os.getenv("KEY"),变量不存在时返回 None。两者都需要在读取之前完成加载。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年8月2日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们