Rocky 10:用 systemd timer 替代 cron
在 Rocky Linux 10.2 特权容器(systemd 257,容器内 PID 1 为 systemd)中实测:写 lab-tick.service + lab-tick.timer、systemctl enable --now、list-timers、手动 start、disable、清理。日志:plans/content-expansion/evidence/logs/rocky-systemd-timers.log。
容器共享宿主内核(5.14),systemd 257 是真实 EL10 用户态;涉及内核调度的行为以真机为准。
为什么用 timer 而不是 cron
Section titled “为什么用 timer 而不是 cron”- 输出进 journal(
journalctl -u),不用自己重定向日志; - 可以声明依赖(
After=、Requires=),和系统启动顺序一致; - 支持
Persistent=true:关机期间错过的任务,开机后补跑一次; - 精度与抖动可控(
AccuracySec、RandomizedDelaySec)。
cron 的优势是短小、跨发行版一致;两者不是替代关系,选哪个取决于是否需要这些能力。
成对的两个文件
Section titled “成对的两个文件”[Unit]Description=lab tick[Service]Type=oneshotExecStart=/usr/local/bin/lab-tick.sh[Unit]Description=lab tick timer[Timer]OnCalendar=*:0/1Persistent=true[Install]WantedBy=timers.targettimer 与 service 必须同名(lab-tick.timer 触发 lab-tick.service)。Type=oneshot 适合「跑完就退出」的脚本。
启用并看下次触发时间
Section titled “启用并看下次触发时间”sudo systemctl daemon-reloadsudo systemctl enable --now lab-tick.timersystemctl list-timers --all | grep -E "lab-tick|NEXT"NEXT LEFT LAST PASSED UNIT ACTIVATESTue 2026-10-20 11:48:00 UTC 2s - - lab-tick.timer lab-tick.serviceNEXT 就是下一次触发时间,ACTIVATES 指向配套的 service。判断 timer 是否生效看这两列,不用猜。
手动触发一次
Section titled “手动触发一次”sudo systemctl start lab-tick.servicetail -2 /var/log/lab-tick.log2026-10-20T11:47:58Z手动 start 跑的是 service,不改变 timer 的排期;用来验证脚本本身没问题。
sudo systemctl disable --now lab-tick.timersudo rm -f /etc/systemd/system/lab-tick.{service,timer} /usr/local/bin/lab-tick.shsudo systemctl daemon-reloaddisable --now 同时停掉并移除 timers.target.wants 里的软链(实测输出 Removed '.../lab-tick.timer')。
- 只 enable service:timer 不会自动启动,
list-timers里没有它; - 文件名不一致:
foo.timer只会触发foo.service; - OnCalendar 写错:
*:0/1是每分钟,不是每小时;用systemd-analyze calendar验证。
练习:建一个每分钟运行的 timer
Section titled “练习:建一个每分钟运行的 timer”sudo tee /etc/systemd/system/lab-tick.service >/dev/null <<'EOF'[Unit]Description=lab tick[Service]Type=oneshotExecStart=/bin/dateEOFsudo tee /etc/systemd/system/lab-tick.timer >/dev/null <<'EOF'[Unit]Description=lab tick timer[Timer]OnCalendar=*:0/1[Install]WantedBy=timers.targetEOFsudo systemctl daemon-reloadsudo systemctl enable --now lab-tick.timersystemctl list-timers lab-tick.timersystemd-analyze calendar '*:0/1'Normalized form: *-*-* *:00/1:00 Next elapse: Tue 2026-10-20 11:50:00 UTC From now: 53s left检查:
list-timers的NEXT在 60 秒内systemd-analyze calendar '*:0/1'输出Next elapse:与Iterationsystemctl status lab-tick.timer为active (waiting)disable --now后list-timers不再显示它
常见问题
timer 到点了但脚本没跑,怎么查?
先 systemctl status <name>.timer 看是否 active,再 journalctl -u <name>.service 看这次触发有没有报错;文件名不匹配时 timer 根本不会触发对应的 service。
Persistent=true 补跑几次?
只补跑一次(错过的窗口合并为一次),不会按错过的次数重复执行;这对备份类任务通常是期望行为。
EL9 和 EL10 的写法一样吗?
timer 单元语法一致;EL10 是 systemd 257、EL9 是 252 左右,个别新选项(如某些 OnCalendar 扩展)需查 man systemd.timer。
- 日志轮转:logrotate 实战
- 重启策略:重启策略
- 防火墙规则:firewalld rich rule