3、设置环境变量:临时设置、永久设置与 Python 中的 os.environ
环境变量怎么设?这是个好问题。很多新手上来就改 /etc/profile,结果系统崩了,一脸懵。我刚开始也干过这事——改完重启,终端直接打不开,吓得我赶紧进单用户模式改回来。
说白了,环境变量的设置分三种场景:临时用一下、永久生效、以及在 Python 代码里动态改。咱们一个一个说清楚。
3.1 临时设置:export 与 set
临时设置,就是只在当前终端会话里有效。关掉终端,或者新开一个窗口,就没了。适合测试、调试、或者临时跑个脚本。
Linux/macOS:export
# 设置一个环境变量
export MY_VAR="hello_world"
# 查看是否生效
echo $MY_VAR
# 一次性设置并启动程序
export DB_HOST="192.168.1.100" && python app.py
注意,export 后面不要加空格,等号两边也不能有空格。我见过有人写 export MY_VAR = "test",结果变量名变成了 MY_VAR 带个空格,坑了自己半天。
Windows:set
REM 临时设置
set MY_VAR=hello_world
REM 查看
echo %MY_VAR%
REM 启动程序
set DB_HOST=192.168.1.100 && python app.py
Windows 的 set 命令也是临时生效。关掉 cmd 窗口就没了。PowerShell 里用 $env:MY_VAR = "hello_world",语法不一样,别搞混。
我的习惯:调试阶段我永远先用临时设置。确认没问题了,再考虑永久化。这样即使写错了,关掉终端重开就好,不会污染系统。
3.2 永久设置:/etc/profile、~/.bashrc 等
永久设置,就是每次登录或打开终端时自动加载。Linux 下有多个配置文件,加载顺序和适用范围不同。我画了张图,帮你理清楚。
推荐做法:改 ~/.bashrc
我个人习惯把自定义环境变量写在 ~/.bashrc 里。原因很简单:每次打开终端都会加载,不影响其他用户,也不怕改坏系统。
# 编辑 ~/.bashrc
vim ~/.bashrc
# 在文件末尾添加
export JAVA_HOME="/usr/lib/jvm/java-11-openjdk"
export PATH="$JAVA_HOME/bin:$PATH"
export APP_ENV="production"
export DB_URL="postgresql://user:pass@localhost:5432/mydb"
# 保存后立即生效
source ~/.bashrc
⚠️ 我曾经踩过的坑:直接在
/etc/profile 里写错了 PATH,导致所有用户登录后连 ls、vim 都用不了。修复方法是进单用户模式,或者用绝对路径 /usr/bin/vim 去改回来。所以,非必要别动系统级文件。
各配置文件的对比
| 配置文件 | 作用范围 | 加载时机 | 推荐用途 |
|---|---|---|---|
| /etc/profile | 所有用户 | 登录时 | 系统级全局变量 |
| /etc/profile.d/*.sh | 所有用户 | 登录时 | 按功能拆分(如 java.sh、python.sh) |
| ~/.bash_profile | 当前用户 | 登录时 | 登录初始化(较少用) |
| ~/.bashrc | 当前用户 | 每次打开终端 | 最常用:别名、PATH、自定义变量 |
| ~/.profile | 当前用户 | 登录时(bash_profile 不存在时) | 兼容其他 shell |
3.3 Python 中修改:os.environ
在 Python 脚本里,我们可以通过 os.environ 来读取和设置环境变量。注意,这种方式只影响当前进程及其子进程,不会修改系统文件。
基本用法
import os
# 读取环境变量
db_host = os.environ.get("DB_HOST", "localhost")
print(f"数据库主机: {db_host}")
# 设置环境变量
os.environ["APP_MODE"] = "development"
os.environ["LOG_LEVEL"] = "DEBUG"
# 检查是否存在
if "API_KEY" in os.environ:
print("API_KEY 已设置")
else:
print("API_KEY 未设置,使用默认值")
# 删除环境变量
del os.environ["TEMP_VAR"]
实际项目中的应用
我在做微服务部署时,经常用这种方式。比如启动脚本里先加载配置,再启动服务:
import os
import subprocess
def setup_environment():
"""根据部署环境设置环境变量"""
env = os.environ.get("DEPLOY_ENV", "development")
if env == "production":
os.environ["DB_POOL_SIZE"] = "20"
os.environ["CACHE_TTL"] = "3600"
os.environ["LOG_FORMAT"] = "json"
elif env == "staging":
os.environ["DB_POOL_SIZE"] = "10"
os.environ["CACHE_TTL"] = "1800"
os.environ["LOG_FORMAT"] = "text"
else:
os.environ["DB_POOL_SIZE"] = "5"
os.environ["CACHE_TTL"] = "60"
os.environ["LOG_FORMAT"] = "text"
print(f"环境 {env} 配置已加载")
# 启动子进程时,环境变量会自动继承
setup_environment()
subprocess.run(["python", "app.py"])
核心要点:
os.environ是一个类字典对象,修改会立即生效- 修改只影响当前进程和子进程,不影响父进程或其他终端
- 子进程(subprocess)会自动继承当前进程的环境变量
- 推荐用
os.environ.get()读取,避免 KeyError
三种方式的对比总结
| 设置方式 | 生效范围 | 持久性 | 适用场景 |
|---|---|---|---|
| export / set | 当前终端会话 | 临时 | 调试、临时测试 |
| /etc/profile / ~/.bashrc | 系统级或用户级 | 永久 | 生产环境、日常开发 |
| os.environ | 当前 Python 进程 | 临时(进程级) | 脚本内部动态配置 |
我的建议:开发时用
~/.bashrc 设置通用变量,用 export 调试特定场景,Python 脚本里用 os.environ 做动态覆盖。三层配合,既灵活又安全。