Linux 环境变量详解(2026 年最新实用版)
环境变量(Environment Variables)是 Linux/Unix 系统中最核心的“全局配置”机制之一。它们是一组键值对,影响 shell、进程、程序的行为。几乎所有开发、运维、部署场景都会频繁接触环境变量。
1. 什么是环境变量?它和普通 shell 变量的区别
| 特性 | 普通 shell 变量 | 环境变量(export 后的变量) |
|---|---|---|
| 作用范围 | 仅当前 shell | 当前 shell 及其所有子进程、子 shell |
| 是否被子进程继承 | 否 | 是 |
| 是否影响外部程序 | 一般不影响 | 会影响(PATH、LD_LIBRARY_PATH 等) |
| 查看命令 | set 或直接 echo $var | env、printenv、export |
| 典型命名 | 小写或随意 | 全大写(约定俗成) |
一句话总结:
普通变量 = 本地变量
环境变量 = 被 export 过的、可以传给孩子的变量
2. 常用查看命令
# 查看所有环境变量(最常用)
env
printenv
# 查看所有 shell 变量(包括未导出的)
set
# 查看单个变量
echo $PATH
echo $HOME
# 查看某个变量是否被导出
export | grep PATH
3. 最核心、最常用的环境变量(必须记住前 10 个)
| 变量名 | 典型值示例 | 作用说明 |
|---|---|---|
| PATH | /usr/local/bin:/usr/bin:/bin:… | 命令查找路径,shell 执行命令时按顺序搜索这些目录 |
| HOME | /home/yourname | 当前用户主目录,几乎所有工具默认从这里找配置文件 |
| USER / LOGNAME | yourname | 当前登录用户名 |
| SHELL | /bin/bash 或 /bin/zsh | 当前 shell 的路径 |
| PWD | /home/yourname/project | 当前工作目录(每次 cd 都会更新) |
| LANG / LC_ALL | en_US.UTF-8 / zh_CN.UTF-8 | 语言、字符编码、排序规则等本地化设置 |
| PS1 | \u@\h:\w\$ | 命令行提示符格式(交互 shell 专用,不是环境变量,但常一起配置) |
| EDITOR / VISUAL | vim / nano | 默认文本编辑器(crontab -e、git commit 等会用到) |
| LD_LIBRARY_PATH | /usr/local/lib:/opt/mylib | 动态链接库(.so)运行时额外查找路径(慎用) |
| LIBRARY_PATH | /usr/local/lib | 编译时静态/动态库查找路径(gcc/ld 使用) |
4. 如何设置环境变量(临时 vs 永久)
4.1 临时设置(只对当前终端有效)
# 方式一:直接 export
export MY_VAR="hello world"
export PATH="$HOME/.local/bin:$PATH" # 最常见写法,加在最前面
# 方式二:一次声明并导出
export MY_VAR=hello
关闭终端就没了。
4.2 永久设置(推荐优先级顺序)
生效范围从小到大排序:
| 文件路径 | 生效时机 | 推荐用途 | 备注 |
|---|---|---|---|
| ~/.bashrc | 每次打开交互 shell | 用户个人别名、函数、临时 PATH 修改 | 最常用,Ubuntu/Debian 默认用这个 |
| ~/.bash_profile 或 ~/.profile | 登录 shell(login shell) | 环境变量、PATH、代理等全局设置 | 登录时执行一次,优先级高于 bashrc |
| ~/.zshrc | zsh 用户 | 同 bashrc | — |
| /etc/profile | 所有用户登录时 | 系统级全局设置(慎改) | — |
| /etc/environment | PAM 阶段,所有进程 | 纯环境变量(无 shell 语法) | 适合无 shell 环境(如 cron、systemd) |
| /etc/profile.d/*.sh | 所有用户登录时 | 安装软件时常用(干净) | 推荐方式 |
最推荐的现代写法(2025–2026 主流做法):
- 个人 PATH、工具变量 → 放
~/.bashrc或~/.zshrc
# ~/.bashrc 最后加
export PATH="$HOME/.local/bin:$HOME/go/bin:$PATH"
export GOPATH="$HOME/go"
export EDITOR=nvim
- 需要登录就生效的(如代理、JAVA_HOME) → 放
~/.bash_profile
# 如果 .bash_profile 不存在就创建
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
export http_proxy=http://127.0.0.1:7890
- 系统级软件(如 cuda、anaconda) → 放
/etc/profile.d/cuda.sh
# sudo vim /etc/profile.d/cuda.sh
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
5. 加载顺序(非常重要,避免踩坑)
登录 shell(如 ssh 登录、图形界面登录)大致顺序:
- /etc/environment
- /etc/profile
- /etc/profile.d/*.sh
- ~/.bash_profile 或 ~/.profile(如果有 .bash_profile 则不读 .profile)
- ~/.bashrc(通常 .bash_profile 里会 source ~/.bashrc)
非登录交互 shell(打开终端):
- 直接读 ~/.bashrc
脚本执行(bash script.sh):
- 不读任何配置文件,除非你显式 source
6. 常见问题与最佳实践
问题1:为什么加了 PATH 还是找不到命令?
→ 新终端没生效? → source ~/.bashrc 或重新打开终端
问题2:LD_LIBRARY_PATH 要不要加?
→ 尽量不要永久加,推荐用:
ldconfig+/etc/ld.so.conf.d/-rpath编译时嵌入patchelf修改 elf- 容器化(Docker)用
ENV
问题3:变量不生效?
→ 检查是否 export 了
→ 检查是否被后面的配置文件覆盖
→ 用 export -p 查看实际导出的变量
问题4:想调试加载过程?
bash -x # 启动一个调试 shell,看每一步执行什么
echo "debug" >> ~/.bashrc # 加 echo 看是否被加载
快速记忆口诀
- 想让命令全局可用 → 改 PATH
- 想让动态库找到 → 慎用 LD_LIBRARY_PATH,优先 ldconfig
- 个人习惯 → ~/.bashrc
- 登录才需要 → ~/.bash_profile
- 全系统统一 → /etc/profile.d/
如果你有具体场景(比如 Anaconda、CUDA、Go、Node、代理、Rust 等),可以告诉我,我可以给出最推荐的配置写法。