經典的 cron 運算式使用剛好五個以空格分隔的欄位——分鐘 (0–59)、小時 (0–23)、日期 (1–31)、月份 (1–12),以及星期 (0–7,其中 0 和 7 都代表星期日)——而且只接受五種語法符記:數值、星號萬用字元、以逗號分隔的清單、含頭含尾的範圍,以及套用於萬用字元或範圍的正整數步進。其他東西——像是 JAN 或 MON 之類的名稱、@daily 之類的別名、問號、秒數、年份欄位,或雜湊排程——都屬於不同的排程器方言,會被嚴格的經典解析器拒絕。精簡的語法容易隱藏錯誤:某個欄位放錯位置,可能讓任務從每小時執行變成每天執行;而一條看似合理的日期規則,也可能匹配到與預期不同的日曆邊界。一份可靠的 cron 解析器速查表因此必須同時涵蓋欄位範圍,以及日期與星期之間的 OR 行為,因為傳統的 crontab 只要任一個受限制的日期欄位匹配就算命中,並不要求兩個都匹配。本指南將逐欄位說明這個規則,接著示範如何在你寫下的運算式送到正式環境排程器之前先加以驗證。

cron parser cheat sheet
Cron 解析器速查表:範圍、步進與範例

Cron 欄位語法一覽

一行經典的 crontab 剛好有五個欄位,以單一空格分隔,由左至右讀取。位置決定了該值的意義,所以交換兩個欄位會在不知不覺中改變排程。分鐘和小時共同決定一天中的時間:* 9 * * * 從 09:00 到 09:59 之間每分鐘都會觸發,因為小時欄位被限制為 9,而分鐘欄位則跑過 0–59 的每一分鐘。下表整理了 Cronie 風格 crontab 檔案所使用、並由 Cron 解析器 接受的傳統數值範圍。

位置欄位允許值備註
1分鐘0–59工作在一小時內觸發的時間點
2小時0–2324 小時制;0 代表午夜
3日期1–31日曆有效性由 JavaScript Date 處理;月底會自動跳過
4月份1–12僅接受數值;JAN、FEB 等不接受
5星期0–70 和 7 都會標準化為星期日

日期與星期是描述日曆日的兩種方式,而下面所述的 OR 規則意味著你很少會想把兩者同時限制住。月份只接受 1 到 12;像 * * * jan-may * 這類運算式不屬於經典語法,會被拒絕。任何超出允許範圍的欄位、空白的清單項目、像 5-3 這種遞減範圍、步進為零,或在第五個欄位之後多出命令文字,都會被拒絕並回傳明確的錯誤訊息,而不是靜默忽略。

特殊字元:*、,、- 和 /

經典格式可辨識四個特殊字元。每個都是一個建構區塊;組合它們就能在不離開數值語法的情況下描述大多數排程。

  • * (星號)——萬用字元,代表「此欄位中的每個有效值」。因此 * * * * * 會每分鐘觸發一次。
  • , (逗號)——清單分隔符。0,15,30,45 * * * * 會在每小時的 15 分、半小時與 45 分整觸發。
  • - (連字號)——含頭含尾的數值範圍。小時欄位中的 8-12 代表 8、9、10、11 與 12。
  • / (斜線)——套用於萬用字元或範圍的正整數步進。*/10 會從欄位最小值開始,每隔十個值選一次;而 10-50/20 則會選出 10、30 與 50。

如果需要在每小時的 00、15、30 與 45 分觸發,有三種語法描述的是同一個排程:*/15、0,15,30,45,以及 0-45/15 這個等價的步進寫法。前兩種最易閱讀。當你把單一數值與帶步進限制的範圍混用時,請記得逗號只是分隔符:0,30-50/10 會解析為 0 加上 30、40 與 50,而不是 0 加上整個 30-50/10 的所有步進結果。符記之間的空白會在校驗時被標準化,所以欄位內多出的空格不會改變意義。

如何使用 Cron 解析器驗證五欄位運算式

解析器會在嘗試計算下次執行時間之前,先強制執行上述規則。每當你手寫一行 crontab 時,特別是只每天觸發一次的工作,請把它當作最後一道檢查。

  1. 依分鐘、小時、日期、月份、星期的順序,輸入剛好五個欄位。前後多出的欄位,或是當作命令的第六個欄位,都會被拒絕。
  2. 僅使用數值、* 萬用字元、逗號清單、含頭含尾的範圍,或像 */15 這類步進。名稱、別名、問號、年份欄位與秒數都不屬於經典格式。
  3. 閱讀標準化後的運算式、各欄位摘要,以及接下來五個匹配時機,這些會以瀏覽器本地時間搭配對應的 ISO UTC 時間戳顯示。
  4. 依據實際執行該工作的排程器之說明文件與所設定的時區來確認運算式,因為解析器並不會改變排程器所依據的時鐘。

如果你的排程器是 Quartz、Kubernetes CronJob、某個雲端 cron 服務,或是任何會加上秒數、年份或星期別名的產品,一個有效的五欄位運算式在那邊可能有不同的意義,或直接被拒絕。Cronie crontab(5) 原始文件 記載了正統的數值語法,而 Oracle Linux cron 指南 以中立於廠商的方式整理了日期欄位的 OR 語意。請把這個解析器當作語法檢查與數值驗證的輔助工具;部署環境仍然決定了工作實際觸發的時間。

日期與星期的 OR 語意

日期欄位是 cron 最容易讓人混淆的單一來源。傳統的 crontab 並不要求兩個欄位都匹配——當日期與星期都受到限制時,只要其中一個受限制的欄位匹配,候選時間就算命中。

請看 0 0 21 * 1。把日期限制為 21、星期限制為 1 (星期一),看起來像是「21 日當天若也是星期一時,於午夜觸發」,但 cron 實際上會在每個星期一觸發,也會在每月 21 日午夜觸發,即使該日並非星期一。若要表達「僅限星期一的 21 日」,你必須把規則與命令中的 shell 邏輯結合,而不是寫在 cron 運算式本身裡。

當兩個日期欄位之一是萬用字元 * 時,另一個欄位就能獨立控制匹配。例如 0 9 * * 1-5 只在平日的 09:00 觸發,因為星期受到限制而日期未受限制。較細微的模式是 0 9 15 * 1,解析器會將其計算為接下來五個星期一與接下來五個 15 日交錯出現——這個集合比大多數人預期的要大,而解析器會樂於顯示出來,讓錯誤在上線前就一目了然。

常用 Cron 範例速查

下方速查表形式的表格整理了開發者最常取用的排程。每一列僅使用數值、* 萬用字元、範圍與步進;可直接複製貼到 crontab 一行中,再用解析器驗證。

排程運算式
每分鐘* * * * *
每 15 分鐘*/15 * * * *
每天午夜0 0 * * *
平日 09:000 9 * * 1-5
每月 1 日 03:3030 3 1 * *
星期日 02:000 2 * * 0
平日 09:00 到 17:00 之間每小時0 9-17 * * 1-5
每小時的 15 分與 45 分0,15,30,45 * * * *

如果想要更結構化、不必死記欄位順序就能從期望的頻率建構運算式,Cron 工作排程指南 會以反向的方式帶你走過同樣的建構區塊。一旦你有一個運算式,請把它貼進 Cron 解析器,確認接下來五次執行時間符合你預期的排程。

限制與安全界線

嚴格的解析器同時也是格式錯誤輸入的安全網。下次執行時間的計算會以整分鐘為單位向前掃描,若在五年內找不到五次匹配就會停止;這可避免像 0 0 29 2 * (2 月 29 日午夜) 這種稀疏的運算式,在等待下一個閏年的過程中把瀏覽器分頁鎖死。日曆有效性由 JavaScript 的 Date 物件處理,因此 31 日會自然跳過沒有 31 日的月份,而 2 月的規則也能正確處理閏年,你不必額外撰寫程式碼。

解析器會拒絕的其他輸入包括:欄位數不是五個、當作命令的第六個欄位、JAN 或 MON 等名稱、@hourly 或 @reboot 等別名、秒數或年份欄位、Quartz 的問號、月底最後一天語法、雜湊排程,以及隨機範圍。這些功能各自存在於某些排程器方言中,但若全部支援,解析器就會變成另一個工具——不再符合你 crontab 檔案所預期的經典 Cronie 語法。解析器刻意不會執行命令、聯繫伺服器或儲存運算式。請把它的輸出視為驗證輔助:在部署關鍵的備份、計費、通知或維護工作之前,先確認正式排程器的時區、日光節約政策、日期欄位語意與支援的擴充功能。

想深入了解,請參閱 邊框圓角產生器速查表:數值與順序