Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

systemd 环境变量 PATH

在 systemd 服务脚本中扩展 PATH 环境变量,可以通过 Environment= 或 EnvironmentFile= 指令在 [Service] 节设置,使用 PATH=/new/path:$PATH 语法追加新路径,或在单独的文件中定义后再引用。

方法一:直接在服务单元文件中扩展(推荐小型修改)

在 systemd 服务单元文件(如 /etc/systemd/system/my-service.service)的 [Service] 段落中添加 Environment 指令:

[Unit]
Description=My Custom Service

[Service]
Type=simple
ExecStart=/usr/local/bin/my_app
# 扩展 PATH,将 /opt/mytools/bin 添加到现有 PATH 的最前面
Environment="PATH=/opt/mytools/bin:$PATH"
# 或者添加在末尾
# Environment="PATH=$PATH:/opt/mytools/bin"
User=myuser

[Install]
WantedBy=multi-user.target

方法二:使用环境变量文件(推荐大型/多服务共享)

创建一个包含环境变量的文件,例如 /etc/sysconfig/my-app-env 或 /etc/default/my-app-env:

# /etc/sysconfig/my-app-env
MY_APP_HOME=/usr/local/myapp
# 追加新的路径
PATH=/usr/local/myapp/bin:$PATH
# 或者用更标准的方式覆盖并追加
# PATH=/opt/new_tools/bin:$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

在 systemd 服务单元文件中使用 EnvironmentFile 指令引用:

[Service]
Type=simple
ExecStart=/usr/local/bin/my_app
EnvironmentFile=/etc/sysconfig/my-app-env
User=myuser

关键点说明

$PATH 引用了系统默认的 PATH 变量值。

路径顺序决定优先级,位于 $PATH 前面的路径会被优先搜索。

修改后需要执行 sudo systemctl daemon-reload 和 sudo systemctl restart my-service 使更改生效。

PATH 错误

# 环境变量
Environment="PATH=/usr/local/jdk/21.0.9/bin:$PATH"
Environment="JENKINS_HOME=/data/jenkins/data"

# 工作目录
WorkingDirectory=/data/jenkins/war

# 启动命令
ExecStart=java -jar jenkins.war --httpPort=8910 --prefix=/jenkins

Failed at step EXEC spawning java: No such file or directory

通常 不是 PATH 配置的问题,而是 systemd 找不到 java 可执行文件。

原因和解决方法如下:

1. 问题原因

你写的 ExecStart 是:

ExecStart=java -jar jenkins.war --httpPort=8910 --prefix=/jenkins

systemd 不会自动加载 shell 环境变量,包括 $PATH。

虽然你用:

Environment="PATH=/usr/local/jdk/21.0.9/bin:$PATH"

但 $PATH 在 systemd 环境中 不被扩展,$PATH 会被当作字面值。

所以 systemd 执行 java 时找不到可执行文件,报 No such file or directory。

2. 正确写法

方法 A:写全路径

ExecStart=/usr/local/jdk/21.0.9/bin/java -jar jenkins.war --httpPort=8910 --prefix=/jenkins

这是最可靠的方法,也是生产环境推荐做法。

方法 B:使用 Environment 指定完整 PATH(不使用 $PATH)

Environment="PATH=/usr/local/jdk/21.0.9/bin:/usr/bin:/bin"
ExecStart=java -jar jenkins.war --httpPort=8910 --prefix=/jenkins

注意:systemd 不会展开 $PATH,必须写完整路径。

方法 C:使用 ExecStart=/bin/sh -c “…"(不推荐生产环境)

ExecStart=/bin/sh -c 'java -jar jenkins.war --httpPort=8910 --prefix=/jenkins'

systemd 会调用 shell 去解析 $PATH,可行但增加一层 shell,调试不方便。

3. 完整 systemd 示例(推荐方式)

[Unit]
Description=Jenkins CI Server
After=network.target

[Service]
Type=simple
User=jenkins
Group=jenkins

Environment="JENKINS_HOME=/data/jenkins/data"

WorkingDirectory=/data/jenkins/war

ExecStart=/usr/local/jdk/21.0.9/bin/java -jar jenkins.war --httpPort=8910 --prefix=/jenkins

Restart=always
RestartSec=5s

StandardOutput=journal
StandardError=journal

LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

4. 注意事项

/data/jenkins/war/jenkins.war 必须存在并有 jenkins 用户访问权限。

日志查看:

journalctl -u jenkins -f

修改 systemd 文件后别忘了:

systemctl daemon-reload
systemctl restart jenkins

✅ 总结

  • systemd 不会展开 $PATH
  • 生产环境推荐 ExecStart 用 java 全路径
  • $PATH 可以设置,但不要写 $PATH,写完整路径即可