systemd定时器→Cron表达式转换工具
将systemd定时器的OnCalendar=语法转换为cron表达式(分 时 日 月 星期)的免费工具。是姊妹工具"Cron转systemd定时器"的逆向转换。支持daily、weekly等命名快捷方式,并在同时指定日期和星期时给出语义差异警告。
systemd组件与cron字段对应表
systemd的OnCalendar=语法各部分与cron表达式的5个字段对应关系如下。
| 位置 | systemd中的对应位置 | cron字段 |
|---|---|---|
| 1 | 时间部分的分(HH:MM:SS中的MM) | 分 |
| 2 | 时间部分的时(HH:MM:SS中的HH) | 时 |
| 3 | 日期部分的日(年-月-日中的日) | 日(日期) |
| 4 | 日期部分的月(年-月-日中的月) | 月 |
| 5 | 星期前缀(例如:Mon、Mon..Fri) | 星期 |
systemd的秒指定(HH:MM:SS中的SS)没有对应的cron字段,转换时会被忽略(若秒不为"00"会显示警告)。
systemd星期缩写与cron星期编号对应表
systemd使用英文星期缩写,而cron使用0~6的数字表示。
| systemd星期缩写 | cron星期编号 |
|---|---|
| Sun | 0 |
| Mon | 1 |
| Tue | 2 |
| Wed | 3 |
| Thu | 4 |
| Fri | 5 |
| Sat | 6 |
systemd命名快捷方式与cron表达式对应表
systemd有"daily"、"weekly"等易读的命名特殊写法,本工具也支持将它们转换为cron表达式。
| OnCalendar= | cron表达式 |
|---|---|
| minutely | * * * * * |
| hourly | 0 * * * * |
| daily / midnight | 0 0 * * * |
| weekly | 0 0 * * 1 |
| monthly | 0 0 1 * * |
| yearly / annually | 0 0 1 1 * |
常见转换示例
| OnCalendar= | cron表达式 | 含义 |
|---|---|---|
| *-*-* *:*:00 | * * * * * | 每分钟执行一次(相当于cron的"* * * * *")。 |
| *:00/15:00 | */15 * * * * | 每15分钟执行一次。 |
| Mon..Fri 09:00:00 | 0 9 * * 1-5 | 在工作日(周一至周五)的9点0分执行。 |
| *-*-01 00:00:00 | 0 0 1 * * | 每月1日的0点0分执行。 |
| *-01-01 00:00:00 | 0 0 1 1 * | 每年1月1日的0点0分执行。 |
| Mon *-*-01 00:00:00 | 0 0 1 * 1 | 同时指定日期(1日)和星期(周一)的示例。systemd中为AND条件(须同时满足),但cron中会被解释为OR条件(满足其一即可),因此转换结果的执行频率会比原OnCalendar表达式更高,请注意。 |
将日期和星期都限制为非"*"的OnCalendar表达式无法准确转换为cron表达式(因为systemd是AND条件,而cron是OR条件)。遇到此类情况请务必确认转换结果的含义。
把 systemd 定时器还原成 cron 式
本工具把 systemd 定时器的 `OnCalendar=` 还原成「分 时 日 月 星期」的 cron 式,`daily`、`weekly` 之类具名的简写亦在照应之列。它正是姊妹工具的反向。
**这一向的转换要当心的是:systemd 写得出的一些东西,cron 表达不来。** `OnCalendar=` 既能**精确到秒**,也能写 `*-*-01..07` 这样的**日期区间**,而 cron 的五个字段一样也容不下。至于 `Persistent=`——停机期间错过的就在开机后补跑——cron 更是没有与之相当之物。**另一点在于日与星期的语义:systemd 把二者当作与,cron 却读作或。** 照搬过去,排程便朝着跑得更勤的一侧偏了,故本工具在遇到这一情形时会示警。
转换的步骤
- 输入 OnCalendar= 的取值 形如 `Mon *-*-* 06:00:00` 可以,`daily` 之类的名称亦可。
- 查看生成的 cron 式 您会得到对应到五个字段的结果。
- 阅读警告 **cron 表达不来的写法,以及语义上的分别,都会被点出来。**
- 誊进 crontab 在其后接上要跑的命令,这一行便可登记了。
用好本工具的小技巧
- 可以直接输入"daily"、"weekly"、"monthly"等命名快捷方式,内部会转换为对应的cron表达式(例如daily会转换为"0 0 * * *")。
- 将日期和星期都指定为非"*"时,将systemd的AND条件转换为cron的OR条件会改变含义。此时请务必确认警告并检查转换结果是否符合预期。
- OnCalendar语法中的年份和秒指定在cron中没有对应字段,转换时会被忽略(会通过警告提示)。
- 在迁移到Kubernetes CronJob(使用cron格式的调度语法)等场景中,本工具可用于将systemd定时器转回cron格式。
- 对于不同时使用星期和日期的简单调度(每小时、每天、每周等),此转换始终准确一致。
这些场景会用到
迁往没有 systemd 的环境
**容器与较老的类 UNIX 系统,有时除了 cron 别无他物。**
读懂既有的定时器
纵然对 `OnCalendar=` 的写法不熟,化作 cron 式后频次便一目了然。
让两套环境保持同样的排程
**生产跑 systemd、开发跑 cron 时,两处配置可彼此对照。**
盘点自己的排程
一并转换,正是核对间隔是否合乎本意的好时机。
排程的术语
- OnCalendar=
- 在 systemd 定时器中言明时刻的键。**星期、日期与时刻可写在同一行里。**
- cron 式
- 以分、时、日、月、星期五个字段表示时刻的写法。**它无法精确到秒。**
- 具名简写
- 为常用周期所起的别名,如 `daily`、`weekly`、`monthly`。
- 语义之别
- **日与星期同时给出时,systemd 读作与,cron 读作或。**
- Persistent=
- 把停机期间错过的运行于开机后补上的设定。**cron 没有与之直接相当之物。**
- crontab
- 写下 cron 排程的那份文件,或编辑它的那条命令。
常见问题
闲话 ― 从systemd定时器"回归"cron意味着什么
技术迁移通常被描述为单向的(从旧机制迁移到新机制),但在实际工作中,反方向的转换也并不少见。将工作负载从采用systemd的主机环境迁移到只支持cron的轻量级容器,或迁移到采用cron格式调度语法的编排工具(如Kubernetes CronJob)时,就需要将OnCalendar语法转换回cron表达式。
这种"逆向转换"之所以不是简单的一对一对应,是因为systemd的OnCalendar语法比cron表达能力更强,具备年级别指定、秒级精度、日期与星期的AND条件组合等cron的5个字段无法完全表达的概念。因此本工具的目标是"准确转换常用的主要模式",对于无法完全覆盖的复杂指定则作为转换错误处理。
同时指定日期和星期时的语义差异(systemd为AND条件,cron为OR条件)是这种逆向转换中最大的陷阱。对于"每月1日"且"星期一"这样的条件,systemd只会锁定"既是1日又是星期一"的那一天,而cron则会在"是1日的日子"或"是星期一的日子"两种情况下都执行。本工具明确警告这一点,正是为了让用户注意到迁移时容易被忽略的这种含义变化。