用 systemd timer 替代 cron 跑定时任务
2026-08-20
把一批定时任务从笔记本(macOS launchd)搬到 Ubuntu 服务器上,我没有选 cron 而是用了 systemd timer。主要原因有三个:日志自动进 journald、错过的时点可以补跑、每个任务能独立设置重启策略。
最小例子
# /etc/systemd/system/nightly-sync.service
[Unit]
Description=Nightly data sync
[Service]
Type=oneshot
WorkingDirectory=/srv/app
ExecStart=/srv/app/.venv/bin/python sync.py
Environment=TZ=Asia/Shanghai
# /etc/systemd/system/nightly-sync.timer
[Timer]
OnCalendar=Mon..Fri 19:30
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now nightly-sync.timer
systemctl list-timers # 看下一次触发时间
journalctl -u nightly-sync # 看历史输出
几个细节
Persistent=true:机器在触发时点关机,开机后会补跑一次。cron 做不到这点。- 常驻型任务用
Type=simple+Restart=on-failure,让进程崩了自动拉起;看门狗之类的监控进程一定单独成一个 unit,别和被监控的进程绑在一起。 - 时区要在 unit 里显式设,服务器默认 UTC 时
OnCalendar会按 UTC 解释。
和 launchd 比
launchd 的 KeepAlive 只在整个脚本退出后才生效,想要"子进程崩了立刻重启"得自己在 shell 里写守护循环。systemd 把这层做进了 unit 配置,脚本本身可以回到只做业务这一件事。