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條件)。遇到此類情況請務必確認轉換結果的含義。

使用提示

  • 可以直接輸入"daily"、"weekly"、"monthly"等命名快捷方式,內部會轉換為對應的cron表示式(例如daily會轉換為"0 0 * * *")。
  • 將日期和星期都指定為非"*"時,將systemd的AND條件轉換為cron的OR條件會改變含義。此時請務必確認警告並檢查轉換結果是否符合預期。
  • OnCalendar語法中的年份和秒指定在cron中沒有對應欄位,轉換時會被忽略(會通過警告提示)。
  • 在遷移到Kubernetes CronJob(使用cron格式的排程語法)等場景中,本工具可用於將systemd定時器轉回cron格式。
  • 對於不同時使用星期和日期的簡單排程(每小時、每天、每週等),此轉換始終準確一致。

常見問題

當遷移到不支援systemd的輕量級Docker容器,或需要在使用cron格式排程語法的Kubernetes CronJob中重現相同的定期執行,或團隊的運維工具只支援cron格式配置時,就需要將現有的systemd定時器配置轉換回cron表示式。

可以。直接輸入"minutely"、"hourly"、"daily"、"weekly"、"monthly"、"yearly"等systemd命名快捷方式,會轉換為對應的cron表示式。

在systemd的OnCalendar語法中,星期指定和日期指定始終是AND條件(須同時滿足)。而在傳統的Vixie cron規範中,若日期和星期都被限制為非"*",則會成為OR條件(滿足其一即可)。因此本工具在檢測到此情況時會顯示警告,提示轉換結果可能比原OnCalendar表示式更寬泛(執行頻率更高)。

由於cron表示式沒有指定年份的欄位,即使OnCalendar表示式中有年份指定(非"*"的值),轉換為cron時也會被忽略。本工具在此情況下會顯示警告,說明轉換結果將不論指定的年份每年都會執行。

本工具涵蓋了姊妹工具cron_to_systemd生成的主要模式(每分鐘、每小時、每天、每週、每月、每年、步進指定、範圍指定、列表指定、星期指定、命名快捷方式),但由於OnCalendar語法比cron表達能力更強,非常複雜的指定(多個年份、秒級的精細重複等)無法用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日的日子"或"是星期一的日子"兩種情況下都執行。本工具明確警告這一點,正是為了讓使用者注意到遷移時容易被忽略的這種含義變化。