Linux 环境变量详解:PATH、export、source 到底是什么?

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

常见原因:

  1. 命令没有安装;
  2. 命令安装了,但不在 PATH 中;
  3. 文件没有执行权限;
  4. 命令名称写错。

例如脚本在:

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。

可能导致 lscatvim 等命令找不到。

正确写法:

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、交叉编译工具链等开发环境配置问题会好排查很多。

相关推荐
tangwangbi7 小时前
Linux 系统配置文件:/etc/profile、~/.bashrc 和 ~/.bash_profile 三者之间的区别与作用
linux·运维·bash
蜀道山老天师7 小时前
Shell Bash变量与运算符(含条件测试与流程控制)
linux·运维·bash
Mr.朱鹏7 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
mengge.cloud7 小时前
存储技术基础小白教程
linux·运维·服务器·wpf·存储
tang777898 小时前
反爬虫场景下代理IP池的动态扩容与失效IP自动清理方案实现
linux·服务器·网络·爬虫代理·住宅代理ip
新时代牛马9 小时前
Linux 系统调用与IPC 完整篇:从syscall 入口、VDSO 到pipe/shm/futex 选型
linux·运维·服务器
fpcc10 小时前
计算机原理—Linux是如何加载可执行文件到内存
linux
野熊佩骑10 小时前
Kubernetes实战系列文章(三) 之 K8S运维常用命令
linux·运维·docker·微服务·云原生·容器·kubernetes
码农客栈11 小时前
linux 设备树下的 platform 驱动编写
linux
小HANN11 小时前
Linux建站实战:CentOS7+LNMP 从零部署 ECShop 开源电商系统
linux·运维·服务器·经验分享