《用 systemd timer 把定时任务从 cron 里搬出来》
很多服务器上还在用 crontab 跑备份、清理和健康检查。它能用,但排障时往往只看得到“到点执行了没有”,看不到这次为什么失败、标准输出去了哪里。如果机器已经在用 systemd 管服务,改用 timer 单元通常更清楚。
一、为什么要换
cron 把调度和要执行的命令写在同一行,环境变量少、日志默认进邮件或直接丢掉。systemd timer 把“什么时候跑”和“跑什么”拆成两个文件:一个 .timer 负责触发,一个 .service 负责实际工作。失败时能用 systemctl status 和 journalctl 直接看退出码和日志,重启后也不用担心 cron 守护进程是否还在。
二、最小例子
假设要把 /usr/local/bin/backup.sh 每天凌晨两点跑一次。先写 backup.service:
[Unit]
Description=Daily backup
[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/backup.sh
再写 backup.timer:
[Unit]
Description=Run backup every day at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Persistent=true 的意思是:如果机器在两点处于关机或休眠,下次开机后会补跑一次,避免错过备份窗口。OnCalendar 的写法比 cron 的五段字段好读,也支持 Mon…Fri 09:00 这种工作日规则。
三、启用与检查
把两个文件放到 /etc/systemd/system/,执行 systemctl daemon-reload,再 systemctl enable --now backup.timer。用 systemctl list-timers 能看到下次触发时间;出问题时用 journalctl -u backup.service -n 50 就能对齐最近一次运行的日志,不必再翻 /var/mail 或猜测重定向写到了哪里。
想先手动验证脚本本身,可以直接 systemctl start backup.service,不用干等到两点。
四、迁移时要注意
- cron 默认环境很精简,systemd 服务同样如此,路径、密钥、工作目录都要在单元文件里写明白,不要依赖某个交互登录才有的变量。
- 如果脚本里用了 % 号,记得 systemd 会把某些百分号当转义,必要时写成 %%。
- 对已经跑得很稳的老任务,不必一夜间全搬;先把最需要看日志的那几条迁过来就够了。
小结
timer 并不是要取代所有 cron,而是在你已经用 systemd 的机器上,让调度、权限和日志走同一套工具。下次再写“每天跑一次”的任务时,可以先问自己:这次失败了我要去哪里看原因?如果答案是 journalctl,那就值得写成一个 timer。
- 点赞
- 收藏
- 关注作者
评论(0)