Linux 环境变量详解:PATH、export、source 到底是什么?
1. 前言
Linux 中很多开发环境问题,本质都是环境变量问题。
常见现象:
- 命令安装了却提示
command not found; - 配置了 Java,但
java找不到; - 修改
.bashrc后没有立即生效; - 脚本里设置变量,退出脚本后变量没了;
export和普通变量分不清;source不知道什么时候用。
本文重点讲清楚:
bash
PATH
export
source
.bashrc
.profile
2. Shell 变量
定义变量:
bash
name=linux
注意:等号两边不能有空格。
错误写法:
bash
name = linux
读取变量:
bash
echo $name
echo ${name}
推荐在拼接字符串时使用 ${}:
bash
echo "${name}_server"
3. 环境变量是什么
普通变量只在当前 Shell 中有效。
环境变量可以传递给子进程。
查看环境变量:
bash
env
printenv
查看某个变量:
bash
echo $PATH
printenv HOME
常见环境变量:
| 变量 | 作用 |
|---|---|
PATH |
命令搜索路径 |
HOME |
当前用户家目录 |
USER |
当前用户名 |
SHELL |
当前默认 Shell |
PWD |
当前目录 |
LANG |
语言环境 |
JAVA_HOME |
Java 安装路径 |
LD_LIBRARY_PATH |
动态库搜索路径 |
4. export 的作用
普通变量不会自动传给子进程。
bash
myvar=hello
bash
echo $myvar
可能没有输出。
使用 export:
bash
export myvar=hello
bash
echo $myvar
子 Shell 中可以看到。
一句话总结:
text
export 把普通 Shell 变量变成环境变量,让子进程可以继承。
常见写法:
bash
export JAVA_HOME=/usr/lib/jvm/java-17
export PATH=$JAVA_HOME/bin:$PATH
5. PATH 是什么
PATH 决定 Shell 到哪些目录中查找命令。
查看:
bash
echo $PATH
示例:
bash
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
多个目录用 : 分隔。
当输入:
bash
ls
Shell 会依次查找:
text
/usr/local/bin/ls
/usr/bin/ls
/bin/ls
找到后执行。
查看命令实际位置:
bash
which ls
6. command not found 的原因
执行命令:
bash
mycmd
提示:
text
command not found
常见原因:
- 命令没有安装;
- 命令安装了,但不在 PATH 中;
- 文件没有执行权限;
- 命令名称写错。
例如脚本在:
bash
/home/user/scripts/hello.sh
可以用完整路径执行:
bash
/home/user/scripts/hello.sh
或者把目录加入 PATH:
bash
export PATH=/home/user/scripts:$PATH
7. 为什么要写 $PATH
如果写:
bash
export PATH=/opt/myapp/bin
会覆盖原来的 PATH。
可能导致 ls、cat、vim 等命令找不到。
正确写法:
bash
export PATH=/opt/myapp/bin:$PATH
或者:
bash
export PATH=$PATH:/opt/myapp/bin
区别:
| 写法 | 含义 |
|---|---|
| 新路径放前面 | 优先使用新目录中的命令 |
| 新路径放后面 | 系统原命令优先 |
8. source 是什么
source 用来在当前 Shell 中执行脚本。
语法:
bash
source filename
等价写法:
bash
. filename
常见用法:
bash
source ~/.bashrc
作用是让 .bashrc 中的配置立即生效。
如果用:
bash
bash ~/.bashrc
是在子 Shell 中执行,里面设置的变量不会影响当前 Shell。
一句话总结:
text
bash script.sh:在子 Shell 执行
source script.sh:在当前 Shell 执行
9. 常见配置文件
| 文件 | 作用 |
|---|---|
/etc/profile |
所有用户登录 Shell 读取 |
/etc/profile.d/*.sh |
系统级环境变量脚本 |
~/.profile |
当前用户登录 Shell 读取 |
~/.bash_profile |
当前用户 Bash 登录时读取 |
~/.bashrc |
当前用户交互式 Bash 读取 |
普通用户最常改:
bash
~/.bashrc
修改后执行:
bash
source ~/.bashrc
全局配置可以放:
bash
/etc/profile.d/custom.sh
10. 临时环境变量
只想让某个命令使用变量:
bash
VAR=value command
示例:
bash
NODE_ENV=production node app.js
LANG=C sort file.txt
这只对当前命令有效,不会污染当前 Shell。
11. unset 删除变量
bash
export TEST=hello
echo $TEST
unset TEST
echo $TEST
删除后输出为空。
12. 脚本中使用环境变量
判断变量是否为空:
bash
if [ -z "$JAVA_HOME" ]; then
echo "JAVA_HOME is not set"
exit 1
fi
设置默认值:
bash
PORT=${PORT:-8080}
echo $PORT
意思是:如果 PORT 没设置,就使用 8080。
13. systemd 和环境变量
手动运行正常,systemd 运行失败,经常是环境变量不同导致的。
systemd 不一定加载用户的 .bashrc。
可以在 service 文件中写:
ini
[Service]
Environment=JAVA_HOME=/usr/lib/jvm/java-17
Environment=APP_ENV=production
ExecStart=/usr/bin/java -jar /opt/app/app.jar
或者使用:
ini
EnvironmentFile=/etc/myapp/myapp.env
14. 常见问题
14.1 PATH 修改后不生效
执行:
bash
source ~/.bashrc
或者重新打开终端。
14.2 sudo 后变量丢失
sudo 默认可能清理环境变量。
可以临时使用:
bash
sudo -E command
但生产环境要谨慎。
14.3 脚本里 cd 后当前终端没变化
如果用:
bash
bash script.sh
脚本在子 Shell 中执行,不影响当前终端。
如果用:
bash
source script.sh
脚本在当前 Shell 执行,会影响当前终端。
15. 小结
环境变量可以这样记:
text
变量:当前 Shell 内部使用
export:导出给子进程
PATH:命令搜索路径
source:在当前 Shell 执行脚本
常用命令:
bash
echo $PATH
env
printenv
export VAR=value
unset VAR
source ~/.bashrc
which command
理解环境变量后,Java、Python、Node、交叉编译工具链等开发环境配置问题会好排查很多。