Linux中自定义systemd计时器需配对.timer和.service文件:.service定义执行逻辑(如backup-job.service),.timer定义触发时间(如backup-job.timer),通过systemctl daemon-reload、enable、start启用,并用list-timers和journalctl验证调试。

在 Linux 中编写自定义的 systemd 计时器单元,核心是配对两个文件:一个 .timer 单元(定义何时触发)和一个对应的 .service 单元(定义要执行什么)。systemd 不支持直接在 timer 文件里写命令,必须通过 service 文件间接调用。
1. 编写目标服务单元(.service)
这是计时器真正要运行的逻辑。建议放在 /etc/systemd/system/(系统级)或 ~/.config/systemd/user/(用户级)。
例如,创建 /etc/systemd/system/backup-job.service:
[Unit] Description=Daily backup script After=network.target <p>[Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh User=root Group=root</p><h1>可选:限制环境、工作目录或超时</h1><p>WorkingDirectory=/root TimeoutSec=300
注意:Type=oneshot 表示任务执行完即退出;若脚本本身是常驻进程,应改用 Type=simple 或其他类型。
2. 编写计时器单元(.timer)
文件名需与 service 文件同名(仅后缀不同),如 backup-job.timer:
[Unit] Description=Run backup job daily at 2:30 AM Requires=backup-job.service <p>[Timer] OnCalendar=<em>-</em>-* 02:30:00 Persistent=true</p><h1>可选:启动时若错过上次时间,是否立即补运行</h1><h1>RandomizedDelaySec=10m # 避免集群中同时触发</h1><p>[Install] WantedBy=timers.target
OnCalendar 支持多种格式:
- *-*-* 02:30:00 — 每天 02:30:00
- Mon,Thu,*,* 08:00:00 — 每周一、四 08:00
- hourly、daily、weekly — 简写(但精度较低,不推荐用于精确调度)
- OnUnitActiveSec=1h — 相对上一次激活后 1 小时(适合间隔型,非日历型)
3. 启用并验证计时器
保存两个文件后,执行以下操作:
- sudo systemctl daemon-reload — 重载单元配置
- sudo systemctl enable backup-job.timer — 开机自启
- sudo systemctl start backup-job.timer — 立即启动计时器(不运行 service)
- systemctl list-timers --all — 查看所有活跃/失效计时器及其下次触发时间
- journalctl -u backup-job.service -n 20 -f — 实时查看服务运行日志
如果 service 运行失败,timer 不会自动重试(除非配合 Restart=on-failure 在 service 中设置)。
4. 调试常见问题
计时器不触发?优先检查这几项:
- 文件名是否严格匹配(xxx.timer 和 xxx.service)
- systemctl status backup-job.timer 是否显示 “loaded active waiting”
- systemctl list-timers 中是否列出该 timer,且 “NEXT” 时间合理
- service 文件中 User= 和权限是否允许执行目标脚本(比如普通用户 timer 无法写 /var/log)
- 脚本开头是否有正确 shebang(如 #!/bin/bash),且有可执行权限(chmod +x)
不复杂但容易忽略。写好 service + timer,reload + enable + start,再用 list-timers 和 journalctl 看一眼,基本就能稳住。


















