首页/系统/信创系统运维速查/环境变量与 profile 配置
命令与包管理65 条

环境变量与 profile 配置

环境变量持久化位置要分清:/etc/profile.d 全局、~/.bashrc 交互 shell、~/.bash_profile 登录 shell;放错位置是“命令在面板里生效、SSH 里没有”的根因。

信创系统运维速查系统更新于 2026-10-13

变量在什么时候被加载

Linux 的环境变量不是全局一处配置就到处生效:登录 shell 与交互 shell 加载的文件不同,非交互脚本、cron 与 systemd 服务基本不读用户 profile。把 JAVA_HOME 之类变量写进 ~/.bashrc,就会出现『终端里好用、面板里或服务里找不到命令』的现象。关键是把变量放对层级:系统级放 /etc/profile.d,用户级区分登录与交互,服务级放 unit 文件。

基本信息

系统级登录/etc/profile、/etc/profile.d/*.sh
用户级登录~/.bash_profile、~/.bash_login、~/.profile
用户级交互~/.bashrc
服务级systemd unit 的 Environment= 与 EnvironmentFile=
临时生效export 仅影响当前会话
权限要求写系统级目录需 root;profile.d 脚本应有合理权限避免被非授权改写

典型使用场景

  • 统一设置 JAVA_HOME、PATH 等全局变量,供所有用户与脚本使用
  • 给单个业务用户配置专属变量而不污染系统
  • 让开机自启的服务读到必要变量,避免手动重启才正常
  • 批量终端迁移时统一 PATH,兼容老脚本里的命令路径
  • 排查『同一条命令在不同入口下行为不一致』的问题

全局配置示例

全局配置示例
sudo tee /etc/profile.d/app-env.sh >/dev/null <<'EOF'
# 全局变量:登录 shell 会自动读取该目录下的 .sh 文件
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export PATH=$JAVA_HOME/bin:$PATH
EOF
chmod 644 /etc/profile.d/app-env.sh      # 权限收紧,避免被非授权写入
source /etc/profile.d/app-env.sh         # 当前会话立即生效
bash -lc 'echo $JAVA_HOME'               # 新登录 shell 验证,确认持久生效

服务与脚本场景

服务与脚本场景
# systemd 服务不读 profile,变量写在 unit 里:
# [Service]
# Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk
# EnvironmentFile=-/etc/sysconfig/myapp

systemctl show myapp -p Environment            # 查看服务实际拿到的变量
env -i bash -lc 'echo $PATH'                   # 模拟最小环境,检查登录加载链是否完整
crontab -l | head                              # cron 环境极简,脚本里最好显式 source 或写全路径

放错位置的典型症状

变量写在哪谁会读到典型症状
~/.bashrc交互 shell图形界面启动的终端有效,SSH 非交互命令无效
/etc/profile.d所有登录 shell交互登录可见;systemd 服务仍读不到
~/.bash_profile该用户登录 shell其他用户与 root 下命令找不到
systemd Environment=仅该服务手工执行脚本正常,服务启动仍报找不到命令
export 当前会话仅当前终端关掉窗口后全部失效
非交互 shell、cron 与 systemd 服务都不会加载 profile 类文件:服务依赖的变量应写进 unit 的 Environment 或 EnvironmentFile,脚本里则用绝对路径或显式 source。
/etc/profile.d 下的脚本会对每次登录执行,权限过宽等于给所有用户留了开机执行代码的入口,应保持 644 且属主为 root。

易错点

  • 把服务需要的变量写进 ~/.bashrc,手工执行正常、服务启动报找不到命令,排查方向常被误导到程序本身
  • 多个 profile.d 脚本都去修改 PATH,追加顺序混乱导致同名命令调用了非预期的版本
  • 写变量时未加 export,子进程读不到,表现为脚本里 echo 有值但程序说变量为空
  • cron 任务里假定 PATH 与登录环境一致,命令找不到却没有任何提示输出
  • 迁移时把老机器的 profile 整包拷过来,里面含已不存在的路径与旧版本 JDK,触发一堆无用告警

数据来源与参考

  • Bash 手册
  • systemd 环境变量文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌