优先写进/etc/environment;它由pam直接读取,不依赖shell类型,对所有用户、cron及systemd user session生效,格式严格为var_name="value",不支持变量展开,修改后需重新登录才生效。

全局变量该写进 /etc/environment 还是 /etc/profile.d/
系统级全局变量,要让所有用户(包括 root、新创建用户、systemd 服务、cron)都能读到,优先选 /etc/environment。它不依赖 shell 类型(bash/zsh/fish 都认),也不执行任何命令,只做纯键值对加载,最接近“操作系统级配置”。/etc/profile.d/*.sh 是次选——它本质是 bash/zsh 的启动脚本片段,会被 /etc/profile source,但 zsh 默认不读 /etc/profile,systemd 服务也常绕过它。
常见错误现象:echo $MY_VAR 在终端里有值,但在 cron 脚本或 systemctl 启动的服务里为空;或者新用户登录后变量完全不见。这就是误用了 /etc/profile.d/ 或 /etc/profile 导致的加载范围缺失。
-
/etc/environment格式严格:必须是VAR_NAME="value",不能含$PATH展开、不能写export、不能调用命令 -
/etc/profile.d/myenv.sh可以用export VAR=$PATH:/opt/app/bin,但只对显式加载它的 shell 生效 - 改完
/etc/environment必须重新登录(不是source,也不是重启机器),新开终端会话才生效
PATH 被覆盖后命令找不到的紧急修复
临时救急:直接运行 export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 恢复基础路径,再追加你的目录,比如 export PATH=$PATH:/opt/myapp/bin。这能立刻让 ls、cp 等命令回来。
根本原因几乎总是:export PATH=/new/path 写死了,漏了 $PATH。尤其在 /etc/environment 里绝对不能这么干——它不支持变量展开,写死就真只剩那一个路径。
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
- 查当前生效的 PATH:
echo $PATH - 定位污染源:
grep -n "PATH=" ~/.bashrc ~/.profile /etc/environment /etc/profile.d/*.sh 2>/dev/null - 恢复默认 PATH 的安全写法(在配置文件中):
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"(注意这是赋值,不是 export)
zsh 用户别碰 ~/.bashrc
如果你用的是 zsh(检查方式:echo $SHELL 返回 /bin/zsh),往 ~/.bashrc 里写 export 完全无效。zsh 默认加载 ~/.zshrc,而不是 ~/.bashrc。
现象:你反复 source ~/.bashrc,echo $MY_VAR 就是没输出;新建终端也一样。这不是环境变量没生效,是根本没被加载。
- 确认当前 shell:
ps -p $$或echo $SHELL - zsh 用户应编辑
~/.zshrc,末尾加export MY_VAR="value",然后source ~/.zshrc - 如果想兼容 bash 和 zsh,可在
~/.zshrc里加source ~/.bashrc(前提是~/.bashrc里没 bash 特有语法)
systemd 服务看不到你设的全局变量
systemd 服务启动时,不走 login shell 流程,也不读 /etc/profile 或 ~/.bashrc,甚至 /etc/environment 的加载也受限于服务定义方式。最可靠的做法是在 service 文件里显式声明:
[Service] Environment="MY_VAR=value" Environment="PATH=/usr/local/bin:/usr/bin:/bin:/opt/myapp/bin"
不要指望 systemctl --user 或 systemctl 自动继承你在终端里 export 的东西——它们是隔离的进程树。
- 验证服务是否读到变量:
systemctl show --property=Environment myservice.service - 避免在
ExecStart=前用export,那只是启动 shell 的局部变量,传不到实际进程 -
/etc/environment对 systemd user session 有效,但对 system-wide service 无效,除非启用PAMEnvironment且配置正确










