下面把“环境变量”从概念到实践系统讲一遍,并给出常见用法、跨平台差异、调试思路与避坑清单。

什么是环境变量?

  • 本质:一组键值对字符串,随进程一起存在,用来影响程序的运行行为(如配置、路径、区域设置、凭证等)。
  • 继承:子进程会继承父进程的环境变量;在子进程里修改不会反向影响父进程。
  • 作用:把“运行时配置”与“代码”解耦,便于同一程序在不同环境(开发/测试/生产)下运行。

生命周期与作用域

  • 进程级别:变量在当前进程及其子进程有效,进程结束就消失。
  • 会话/用户级别:写到用户的配置文件(如 ~/.bashrc、PowerShell 配置)后,新开的终端都会有。
  • 系统级别:对所有用户生效(Linux 多在 /etc/environment、Windows 在系统环境变量里)。

常见环境变量

  • 路径:PATH(可执行文件查找路径),LD_LIBRARY_PATH/DYLD_LIBRARY_PATH(类 Unix 动态库路径),PYTHONPATHNODE_PATH
  • 本地化:LANGLC_ALLTZ
  • 网络:HTTP_PROXYHTTPS_PROXYNO_PROXY
  • 认证/配置:DATABASE_URLAWS_ACCESS_KEY_IDPORT 等(应用自定义)

查看与设置

Linux / macOS(bash/zsh)

# 查看
printenv        # 或 env
echo "$PATH"

# 临时设置(仅当前 shell 有效)
FOO=bar
export FOO=bar  # export 后子进程也能看到

# 一次性传给某个命令
FOO=bar myprog --flag

# 持久化:写入 shell 启动文件
echo 'export FOO=bar' >> ~/.bashrc    # bash
echo 'export FOO=bar' >> ~/.zshrc     # zsh

Windows(CMD)

:: 查看
set
echo %PATH%

:: 临时设置(当前会话)
set FOO=bar

:: 持久化(写入用户/系统环境)
setx FOO "bar"             :: 新开窗口后生效

Windows(PowerShell)

# 查看
Get-ChildItem Env:
$Env:PATH

# 临时设置
$Env:FOO = "bar"

# 持久化(当前用户)
[Environment]::SetEnvironmentVariable("FOO","bar","User")

注意:Windows 的环境变量大小写不敏感;路径分隔符多为 ;(而类 Unix 为 :)。

在程序里读取

  • Python

    import os
    os.environ.get("FOO", "default")
    
  • Node.js

    process.env.FOO ?? "default";
    
  • Java

    System.getenv("FOO");
    
  • Bash 脚本

    echo "${FOO:-default}"   # 没有就用默认值
    

.env 文件与 dotenv

  • 习惯把本地开发配置写到 .env(纯文本:KEY=value)并加入 .gitignore

  • 运行时用库加载:

    • Node:dotenvrequire('dotenv').config()
    • Python:python-dotenv
  • 生产环境更推荐用真正的环境变量密钥管理服务(而不是在服务器上放 .env 文件)。

PATH 与可执行查找

  • 类 Unix 用 : 分隔:/usr/local/bin:/usr/bin:...

  • Windows 用 ; 分隔:C:\Program Files\...\bin;...

  • 追加示例(bash):

    export PATH="$HOME/.local/bin:$PATH"
    
  • 排查可执行不生效时,先 echo $PATH / where(Win) / which(Unix)。

变量展开与默认值(bash)

"${VAR:-default}"   # VAR 未设或空 => default
"${VAR:=default}"   # 若未设则赋值为 default
"${VAR:?message}"   # 未设则报错并退出
"${VAR:+alt}"       # 设了就用 alt,否则空

跨平台差异速记

  • 分隔符:PATH(Unix :,Windows ;
  • 大小写:Windows 环境变量名不区分大小写;Unix 区分
  • 换行与转义.env 中包含空格/特殊符号需引号或转义(FOO="a b"
  • 编码:尽量使用 UTF-8;与外部程序交互注意本地化变量(LANG 等)

安全与合规实践

  • 不要把密钥写进仓库.env 一律进 .gitignore
  • 最好用秘密管理(KMS、Vault、Secrets Manager、Kubernetes Secret)。
  • 设置最小权限、定期轮换;生产与开发隔离不同凭证。
  • 日志与错误信息中避免打印敏感变量(redact)。

容器与编排

  • Docker

    # Dockerfile
    ENV APP_ENV=production
    
    docker run -e APP_ENV=prod --env-file .env myimage
    
  • Kubernetes

    • env 直接写死或来源于 ConfigMap/Secret
    • 可用 valueFrom.secretKeyRef 注入密钥
  • 容器镜像要避免把秘密“烘焙”进去;运行时注入。

调试与排错思路

  1. 确认可见性:在程序前加 env | sort 看关键变量是否传入。
  2. 确认加载顺序:交互式 shell vs 登录 shell,~/.bashrc~/.profile 哪个执行了?
  3. 确认服务管理器systemdcron、CI/CD 的环境通常与交互式 shell 不同。
  4. 最小化复现:写个小脚本只打印 process.env/os.environ

常见陷阱清单

  • 忘记 export(只成了 shell 变量,子进程不可见)。
  • PATH 追加写错顺序,导致调用到旧版本。
  • .env 里有尾随空格/引号,解析出错。
  • Windows 与 Unix 分隔符混用,PATH 失效。
  • 在容器/服务里以为加载了 ~/.bashrc,实际没有。
  • 把密钥打进镜像或写进代码库。

速用小抄

类 Unix

printenv | sort
export KEY=value
KEY=value cmd            # 临时传给某个命令
echo 'export KEY=value' >> ~/.bashrc && source ~/.bashrc
which myprog             # 查找可执行

Windows(PowerShell)

Get-ChildItem Env:
$Env:KEY = "value"
[Environment]::SetEnvironmentVariable("KEY","value","User")

Node

npm i dotenv
# index.js
require('dotenv').config();
console.log(process.env.KEY);

Python

pip install python-dotenv
# app.py
from dotenv import load_dotenv; load_dotenv()
import os; print(os.environ.get("KEY"))

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐