systemd 单元文件生成器
按表单生成 service 与 timer 配置,同时提示常见的启动失败原因。生成的只是文本,不会写入服务器。
单元配置
简单模式常驻进程,异常退出后自动重启;记得把 User 换成实际运行用户。
无需填写 .service / .timer 后缀,生成时自动补全。
必须使用绝对路径,且不经过 shell。
每行一个 KEY=VALUE,前面加 # 的行会被忽略。
留空时默认写入 network.target。
生成的单元文件
/etc/systemd/system/my-app.service[Unit] Description=My application After=network.target [Service] Type=simple ExecStart=/usr/local/bin/my-app Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
部署步骤
- sudo systemctl daemon-reload
- sudo systemctl enable --now my-app.service
- systemctl status my-app.service
- journalctl -u my-app.service -f
配置提醒
未指定 User,服务将以 root 身份运行;如无必要建议改为专用低权限用户。
生成的仅是配置文本,工具不会连接服务器、写入文件或重启任何服务。修改单元文件后需要先执行 daemon-reload 才会生效。
单元文件放在哪里
自己维护的单元文件放在 /etc/systemd/system/;软件包安装的单元位于 /usr/lib/systemd/system/。需要覆盖发行版默认配置时,优先新建 *.service.d/override.conf 片段,而不是直接修改软件包自带文件。
写入文件后必须执行 systemctl daemon-reload 让 systemd 重新读取配置,再用 systemctl enable --now 启用并立即启动。
常用字段速查
| 字段 | 所在段 | 说明 |
|---|---|---|
| Description | [Unit] | 单元用途说明,出现在 systemctl status 与日志中。 |
| After / Requires | [Unit] | 声明启动顺序与依赖;After 只排序,不表示对方一定成功启动。 |
| Type | [Service] | simple 适用于前台常驻进程,forking 用于自行后台化的老式程序,oneshot 用于执行完即退出。 |
| ExecStart | [Service] | 必须写绝对路径,不经过 shell,因此 &&、管道和重定向不会生效。 |
| Restart / RestartSec | [Service] | Restart 决定何时重启进程,RestartSec 决定间隔,默认 100ms 容易形成重启风暴。 |
| User / Group | [Service] | 不写则以 root 运行,建议改为专用低权限用户并配合目录属主设置。 |
| Environment | [Service] | 通过 KEY=VALUE 注入环境变量,多个变量写多行。 |
| OnCalendar | [Timer] | 定时器的触发时间,支持 daily、weekly 等简写或 *-*-* 03:00 这类表达式。 |
| Persistent | [Timer] | 开机后补跑关机期间错过的任务,需要任务自身可重复执行。 |
| WantedBy | [Install] | 决定 enable 时建立哪些符号链接;timer 通常使用 timers.target。 |
启动失败怎么排查
- 用
systemctl status 单元名查看退出码与最近日志,再用journalctl -u 单元名 -n 50看完整输出。 - 出现
status=203/EXEC通常是 ExecStart 路径错误或文件没有执行权限。 - 出现
status=200/CHDIR是 WorkingDirectory 不存在;status=209/STDOUT则要检查日志文件路径与权限。 - 服务反复重启时先看
Result=字段,并临时把 Restart 改为 no 定位问题。 - 定时器不触发时用
systemd-analyze calendar '表达式'验证时间,并确认已enable --now的是 .timer 而不是 .service。
常见问题
为什么 Type=oneshot 不建议配合 Restart?
oneshot 的进程会正常退出,systemd 无法区分“任务完成”和“异常退出”,自动重启容易造成重复执行。周期性任务应交给 timer 调度。
服务和定时器需要同名吗?
不是强制的,但同名(如 backup.timer 触发 backup.service)便于维护。不同名时必须在 timer 中显式写 Unit= 指定被触发的单元。
Restart=always 和 on-failure 怎么选?
always 适合必须常驻的守护进程;on-failure 只在非零退出码或被信号终止时重启。两者都必须设置 RestartSec。
工具会直接修改服务器配置吗?
不会。页面只生成文本,复制后需要自行登录服务器创建文件并执行 daemon-reload 与 enable。请先用 systemctl cat 确认没有被覆盖或冲突的配置。