env只显示已导出的环境变量,set显示所有变量(含局部变量和函数),echo $VAR仅查单个变量值;未export的变量在env中不可见,需用set确认定义、env或declare -p确认导出。

直接看结论:用 env 查当前 shell 的全部环境变量(即已导出的全局变量),用 set 才能同时看到局部变量;echo $VAR 仅适合查单个变量值,但无法判断它是否被导出。
为什么 env 看不到你刚定义的变量?
因为 env 只显示「已导出」的环境变量——也就是子进程能继承的那一部分。如果你只写了 MY_VAR=value,没加 export,它只是 shell 的局部变量,env 就不会列出来。
-
MY_VAR=hello→ 局部变量,env | grep MY_VAR找不到 -
export MY_VAR=hello→ 导出后,env和子进程(如bash -c 'echo $MY_VAR')都能访问 - 临时补救:已定义但未导出?直接补一句
export MY_VAR即可,不用重赋值
set 和 env 的关键区别在哪?
set 输出的是当前 shell 的所有变量(含函数、局部变量、环境变量),而 env 只输出导出后的环境变量。所以当你怀疑某个变量“存在但不生效”,优先用 set | grep VAR 确认它是否被定义,再用 env | grep VAR 确认它是否被导出。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
-
set输出里带declare -x前缀的,就是已导出的环境变量(和export命令单独执行时的格式一致) -
set会混入大量 shell 内置变量(如BASH_VERSION、UID),实际排查时建议配合grep -v '^_='过滤掉内部变量 - 注意:
set不受shopt -s expand_aliases影响,别指望它显示 alias
怎么查某个变量到底是全局还是局部?
最可靠的方式是组合使用两个命令:
- 查是否定义:
set | grep '^MY_VAR='(注意^和=,避免匹配到其他变量名含 MY_VAR 的项) - 查是否导出:
env | grep '^MY_VAR='或declare -p MY_VAR 2>/dev/null | grep -q 'declare -x' - 如果只在
set中出现、不在env中,说明它是局部变量;两者都出现,才是真正的环境变量 - 补充技巧:在子 shell 中测试,
bash -c 'echo $MY_VAR'能输出值,才说明它真正“全局”可继承
容易被忽略的一点:变量名大小写敏感,且 PATH 和 path 是两个完全不同的变量;另外,有些变量(如 PS1)默认是局部的,即使你常改它,也不会自动导出——这点在写启动脚本时特别容易踩坑。

















