程序环境变量


🧩 一、什么是环境变量(Environment Variable)

环境变量 本质上是:

一组 “键=值” 形式的字符串,用来告诉程序运行时的系统信息或配置。

它存在于进程的运行环境(Environment)中。


🧠 二、系统 vs 程序 的区别

分类 说明 举例 谁来设置
系统环境变量 操作系统级别的变量,对所有用户/进程可见 PATH, HOME, TEMP, OS, LANG 系统或管理员
用户环境变量 当前用户可见,只影响该用户启动的进程 JAVA_HOME, PYTHONPATH 当前登录用户
程序环境变量 程序启动时继承系统/用户变量,也可以在运行时新增/覆盖 DATABASE_URL, SECRET_KEY, PORT 启动命令 / Docker / .env 文件等

🔹 换句话说:

程序启动时,会从操作系统继承一份环境变量表,
这份表就是它的“运行环境”。


🧩 三、环境变量的作用范围

层级 示例 生效范围
系统级 Windows:系统属性 → 环境变量
Linux:/etc/environment/etc/profile
所有用户、所有进程
用户级 Windows:用户环境变量
Linux:~/.bashrc, ~/.profile
当前用户
进程级 启动命令中设置的变量 当前进程及其子进程
容器级 Docker environment.env 仅容器内有效

🧠 四、常见环境变量类型(按用途)

类型 说明 常见示例
系统路径类 定义可执行文件、库路径等 PATH, LD_LIBRARY_PATH, CLASSPATH
区域语言类 设置语言、字符集 LANG, LC_ALL
配置参数类 应用程序自己的配置 DATABASE_URL, SECRET_KEY, REDIS_HOST
运行控制类 控制日志级别、调试模式 DEBUG, LOG_LEVEL
容器编排类 在 Docker/K8s 中用于连接不同服务 SERVICE_HOST, SERVICE_PORT, ENV

🧱 五、Docker 环境变量的层级关系

在 Docker 中,变量来源有多个层次,优先级如下(从高到低):

来源 示例 说明
docker run -e KEY=value CLI 手动指定 最高优先级
docker-compose.ymlenvironment Compose 内定义 覆盖 .env 文件
.env 文件 默认环境文件 Compose 自动加载
镜像内 ENV 指令 Dockerfile 中定义 镜像内默认值
宿主系统变量 系统传入 仅显式引用时传入(如 $VAR

举个例子:

1
2
# Dockerfile
ENV APP_ENV=prod
1
2
3
# docker-compose.yml
environment:
- APP_ENV=dev

运行后容器里的 APP_ENV = dev(后者覆盖前者)。


🧰 六、Python 中读取环境变量

Python 程序启动时,会自动加载父进程(系统/容器)环境:

1
2
3
4
5
import os

print(os.environ) # 所有环境变量
print(os.getenv("PATH"))
print(os.getenv("SECRET_KEY", "default_value"))

你也可以运行时手动添加:

1
os.environ["DEBUG"] = "True"

(⚠️ 这种方式只在当前进程内有效,不会影响系统)


⚙️ 七、不同平台的定义方式

系统 临时设置(当前命令) 永久设置(系统/用户级)
Linux / macOS export KEY=value ~/.bashrc, /etc/profile
Windows CMD set KEY=value 系统属性 → 环境变量
Windows PowerShell $env:KEY="value" [Environment]::SetEnvironmentVariable(...)

🧭 八、总结对比表

层级 示例 是否持久 作用范围
系统环境变量 PATH, JAVA_HOME 所有用户
用户环境变量 PYTHONPATH 当前用户
程序环境变量 SECRET_KEY ❌(随程序结束消失) 当前程序或容器
Dockerfile ENV ENV APP_ENV=prod ✅(镜像层保存) 所有基于该镜像的容器

🌟 直观理解

可以把环境变量想象成:

“程序启动前告诉它的一组全局设置”,
它不是写在代码里,而是外部传入的配置。

比如:

1
2
3
4
5
# 开发环境
SECRET_KEY=devkey python app.py

# 生产环境
SECRET_KEY=prodkey gunicorn app:app

程序代码不变,但行为完全不同。