跳转到内容
搜索 Rocky Linux 文档

    浏览当前文档目录

    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 用户态;涉及内核调度的行为以真机为准。

    • 输出进 journal(journalctl -u),不用自己重定向日志;
    • 可以声明依赖(After=、Requires=),和系统启动顺序一致;
    • 支持 Persistent=true:关机期间错过的任务,开机后补跑一次;
    • 精度与抖动可控(AccuracySec、RandomizedDelaySec)。

    cron 的优势是短小、跨发行版一致;两者不是替代关系,选哪个取决于是否需要这些能力。

    /etc/systemd/system/lab-tick.service
    [Unit]
    Description=lab tick
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/lab-tick.sh
    /etc/systemd/system/lab-tick.timer
    [Unit]
    Description=lab tick timer
    [Timer]
    OnCalendar=*:0/1
    Persistent=true
    [Install]
    WantedBy=timers.target

    timer 与 service 必须同名(lab-tick.timer 触发 lab-tick.service)。Type=oneshot 适合「跑完就退出」的脚本。

    Terminal window
    sudo systemctl daemon-reload
    sudo systemctl enable --now lab-tick.timer
    systemctl list-timers --all | grep -E "lab-tick|NEXT"
    NEXT LEFT LAST PASSED UNIT ACTIVATES
    Tue 2026-10-20 11:48:00 UTC 2s - - lab-tick.timer lab-tick.service

    NEXT 就是下一次触发时间,ACTIVATES 指向配套的 service。判断 timer 是否生效看这两列,不用猜。

    Terminal window
    sudo systemctl start lab-tick.service
    tail -2 /var/log/lab-tick.log
    2026-10-20T11:47:58Z

    手动 start 跑的是 service,不改变 timer 的排期;用来验证脚本本身没问题。

    Terminal window
    sudo systemctl disable --now lab-tick.timer
    sudo rm -f /etc/systemd/system/lab-tick.{service,timer} /usr/local/bin/lab-tick.sh
    sudo systemctl daemon-reload

    disable --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”
    Terminal window
    sudo tee /etc/systemd/system/lab-tick.service >/dev/null <<'EOF'
    [Unit]
    Description=lab tick
    [Service]
    Type=oneshot
    ExecStart=/bin/date
    EOF
    sudo tee /etc/systemd/system/lab-tick.timer >/dev/null <<'EOF'
    [Unit]
    Description=lab tick timer
    [Timer]
    OnCalendar=*:0/1
    [Install]
    WantedBy=timers.target
    EOF
    sudo systemctl daemon-reload
    sudo systemctl enable --now lab-tick.timer
    systemctl list-timers lab-tick.timer
    systemd-analyze calendar '*:0/1'
    Normalized form: *-*-* *:00/1:00
    Next elapse: Tue 2026-10-20 11:50:00 UTC
    From now: 53s left

    检查:

    1. list-timers 的 NEXT 在 60 秒内
    2. systemd-analyze calendar '*:0/1' 输出 Next elapse: 与 Iteration
    3. systemctl status lab-tick.timer 为 active (waiting)
    4. 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。