OnCalendar 是什么
OnCalendar 是 systemd timer 里用来描述「何时触发」的日历表达式,写法接近「星期 年-月-日 时:分:秒」的组合,也可以用 daily、weekly 这类简写。它比 cron 的五段表达式更贴近自然语言,但也更容易写错,所以 systemd 提供了 systemd-analyze calendar 做静态验证,直接告诉你规范化的表达式与下次触发时间。
基本信息
| 适用平台 | Linux(systemd 的 .timer 单元) |
|---|---|
| 表达式形态 | [星期] [年-月-日] [时:分:秒],各段可用 * 通配、.. 表示范围、/ 表示步进 |
| 常用简写 | minutely、hourly、daily、weekly、monthly、yearly |
| 验证命令 | systemd-analyze calendar '表达式',输出规范化结果与下次触发时间 |
| 配套参数 | OnBootSec、OnUnitActiveSec 属于相对触发,与 OnCalendar 是两套机制 |
典型使用场景
- 固定时刻任务:每天凌晨执行备份,用每天 03:30 的表达
- 仅工作日执行:用星期范围限制在周一到周五
- 高频轮询:用步进表达式实现每 15 分钟一次
- 避开整点拥堵:用非整点分钟错开大量机器的同时触发
- 排查定时器不触发:用 analyze 验证表达式是否被正确解析
常用表达式
常用表达式
systemd-analyze calendar 'daily' # 每天 00:00
systemd-analyze calendar '*-*-* 03:30:00' # 每天凌晨 3:30
systemd-analyze calendar 'Mon..Fri 08:00' # 工作日早上 8 点
systemd-analyze calendar '*:0/15' # 每 15 分钟
systemd-analyze calendar 'weekly' # 每周一 00:00
systemd-analyze calendar '*-*-01 02:00:00' # 每月 1 日凌晨 2 点验证输出读法
验证输出读法
Normalized form: Mon..Fri *-*-* 08:00:00
Next elapse: Mon 2026-10-19 08:00:00 CST
(in UTC): Mon 2026-10-19 00:00:00 UTC
From now: 5 days left表达式构成读法
| 字段 | 含义 | 写法示例 |
|---|---|---|
| 星期 | 限定在周几触发 | Mon..Fri 表示周一到周五 |
| 年-月-日 | 限定日期 | * 通配,01 表示每月 1 号 |
| 时:分:秒 | 限定具体时刻 | 03:30:00 表示 3 点 30 分 |
| 步进 | 按间隔重复 | *:0/15 表示每小时的第 0 分起每 15 分钟 |
| 范围 | 用两个点表示区间 | Mon..Fri、09..17 |
| 简写 | 预定义的常用周期 | daily、weekly、monthly、yearly |
改完 .timer 里的表达式,要先 systemctl daemon-reload,再 restart 对应的 timer,最后用 systemctl list-timers 复核 NEXT 列是否是预期时刻。只改文件不重载再重启,排期仍按旧表达式走。
表达式默认使用系统本地时区:云主机常把系统时区设为 UTC,此时写 03:00 触发的其实是北京时间 11:00。验证输出里的 UTC 一行是同一时刻的 UTC 表示,把它与预期时刻对照一下,就能立刻发现自己是不是搞错了时区。
要与 OnUnitActiveSec 一类相对触发区分开:OnCalendar 描述的是日历上的固定时刻,相对触发描述的是距上次激活的间隔。需要「每天固定钟点跑」用前者,需要「服务跑完若干分钟后再来一次」用后者;把两者塞进同一个 timer 时,实际触发节奏会变得难猜,两种需求建议拆成两个 timer 分别管理与验证。