用 systemd timer 替代 crontab 做备份
crontab 够用,但它有两个老问题:日志散在邮件里,失败后没人知道;机器关机错过时间点,这一轮就永久跳过了。systemd timer 在这两件事上更省心。
两个文件
服务单元负责“做什么”,定时单元负责“什么时候做”。
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup every night
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target
关键是 Persistent=true:关机期间错过的任务,开机后会补跑一次。这个行为对备份很重要,cron 默认不会。
启用与验证
systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers --all
journalctl -u backup.service -n 50
systemctl list-timers 会直接告诉你下次触发时间,比推算 cron 表达式快得多。
几点注意
- 脚本里尽量用绝对路径,systemd 不加载用户的环境变量
- 用
Type=oneshot,任务跑完服务才结束,状态才准确 - 失败想重试可以加
Restart=on-failure和RestartSec= - 输出到 stdout 的内容会进 journal,不用自己再写日志文件
什么时候还是用 cron
临时的一次性任务、需要以普通用户身份在任意目录跑的小脚本,crontab -e 依然更快。systemd 适合那些需要被监控、需要可追溯的长期任务。