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