在 Linux 中,cron 工作是一個排程的 shell 指令,會依照固定間隔自動執行,其定義來自 crontab 檔案內一個五個欄位的運算式。這五個欄位依序為分鐘、小時、日期、月份和星期幾,每個欄位都可接受數字、範圍、萬用字元或步進值,例如 */15 代表每 15 分鐘。建立 cron 工作的方式是寫下該運算式,在後面加上你想執行的指令,然後將該行儲存到正確的 crontab 中,讓 cron 守護程式去讀取。困難的部分通常不是指令本身,而是在挑選欄位值時,既要符合你真正想要的排程,又不會忘記哪一欄是月份、哪一欄是星期幾。Cron 運算式產生器會將七種常見預設(每分鐘、每 N 分鐘、每小時、每天、平日、每週、每月)對應到標準的 crontab 欄位,讓你能用淺顯易懂的英文描述排程,然後複製結果。之後,你只需要把該行貼到使用者個人的 crontab 或全系統檔案中,並確認排程器的時區即可。

how to create a cron job in linux
how to create a cron job in linux

Linux Cron 工作實際包含的內容

crontab 項目其實只是用空白串接在一起的兩部分:一個排程運算式和一個 shell 指令。排程部分是五個欄位的 cron 運算式,而指令可以是單一可執行檔路徑、腳本呼叫,或是以管線串接的 shell 命令。cron 守護程式會在啟動時、使用者執行 crontab -e 時,以及定期重新載入時重新讀取 crontab,因此編輯後不需要重新啟動伺服器就能生效。

每位使用者都可以擁有自己的 crontab,root 則可以編輯 /etc/crontab 內的全系統排程,或將檔案放入 /etc/cron.d。運算式本身只描述時間,並不包含指令、工作目錄、環境變數、重試、鎖定或監控。這些都必須放在五個欄位之後所附加的指令中,這也是為什麼包裝腳本通常是最安全的地方,用來放置真正的邏輯並記錄執行結果。

用淺顯易懂的方式說明五個欄位的 Cron 運算式

傳統 crontab 要求的固定順序中,五個欄位依序為:分鐘、小時、日期、月份和星期幾。產生器將分鐘限制在 0 到 59 之間、小時限制在 0 到 23 之間、星期限制在星期日 0 到星期六 6 之間、日期限制在 1 到 31 之間,因此你不會不小心輸入超出範圍的值。下表彙整了每個欄位的標準範圍與簡短範例。

PositionFieldRangeExampleMeaning
1Minute0-59*/15Every 15 minutes
2Hour0-239At 9 a.m.
3Day of month1-311On the first day
4Month1-12*Every month
5Day of week0-6 (0 and 7 = Sunday)1-5Monday through Friday

在任何欄位中,星號代表該欄位的所有有效值,因此小時欄位中的 * 代表每一小時都執行。逗號可列出特定值,連字號定義包含首尾的範圍,而斜線則代表步進。在標準的 Unix 編號中,星期欄位 1-5 代表週一到週五,實作方式遵循 Linux man-pages crontab(5) 參考文件中所記載的標準 crontab(5) 語法。

使用 Cron 運算式產生器建立排程

想為你想要的排程取得正確的五欄運算式,最快的方法是使用 Cron 運算式產生器,它會將有範圍限制的排程預設對應到標準的 crontab 欄位。開啟工具後請依照下列步驟操作。

  1. 從七個預設中,選擇符合工作頻率的排程類型:每分鐘、每 N 分鐘、每小時、每天、平日、每週或每月。
  2. 設定該排程所顯示的間隔、分鐘、小時、星期或日期,因為相關控制項只會在你選擇的預設中出現,而產生的運算式加上淺顯易懂的摘要會立即更新。
  3. 複製五個欄位的運算式,在目標排程器和時區中驗證後,再加入指令。

這些預設刻意避免同時設定日期與星期,因為這個組合會觸發實作特定的 OR 行為,在某些 cron 實作中可能產生非預期的符合。產生過程完全在本地端進行,不會上傳任何指令或排程,因此離開瀏覽器的只有你複製的運算式字串。

你在產生運算式中會看到的符號

產生器僅使用 crontab(5) 文件中所記載的萬用字元、步進、固定值與包含首尾的星期範圍語法,因此輸出結果能與 Linux 上傳統 Unix 風格的 crontab 項目相容。

SymbolMeaningExampleResult
*Every valid value in the field*Every minute (in the minute field)
,List of values0,30At minutes 0 and 30
-Inclusive range1-5Monday through Friday
/Step value*/10Every 10 minutes

因為產生器僅使用這四種語法形式,所以你可以將結果直接貼到標準的 Linux crontab 中,無需任何轉換。如果你之後想確認該行程式會在預期的時間觸發,可以將它送入 Cron Parser,查看同一運算式接下來幾個符合的時間戳記。

Linux Cron 工作中常見的陷阱

即使運算式正確,有幾個 Linux 特有的行為仍會在第一次部署時讓人踩坑。在依賴該排程之前,請留意下列事項。

  • Cron 執行時使用的是排程器設定的時區,不一定是你工作站顯示的時區。請檢查 /etc/timezone 或守護程式啟動時所使用的 TZ 值。
  • 日光節約時間的切換可能會略過或重複本地牆上時間,因此排程在春季提前當週日凌晨 2:30 的工作,當天可能永遠不會執行。
  • 每月 29、30 或 31 日執行的每月工作,在不含該日期的月份會被靜默略過,而二月最常發生這種情況。
  • 運算式只描述時間,因此不含重試、鎖定或監控。請使用具等冪性的指令、將失敗寫入記錄檔,並在工作可能跨越間隔時,防止重疊執行。

將運算式加入你的 Linux Crontab

安全的作業流程是先在產生器中選擇排程、複製五個欄位的運算式,然後才在目標 crontab 中加入指令。若要編輯目前使用者的 crontab,請在 shell 中執行 crontab -e;若要編輯 root 的 crontab,請使用 sudo crontab -e。若要加入全系統的排程,請將檔案放到 /etc/cron.d/ 中,或加入 /etc/crontab,該檔案使用略有不同的六欄格式,並包含使用者欄位。

一般格式為五個欄位,後面接著指令:

<minute> <hour> <day> <month> <weekday> /path/to/command args

舉例來說,在產生器中選擇「每週一至五上午 09:30」後,你可能會貼上:

30 9 * * 1-5 /opt/backup/run.sh >> /var/log/backup.log 2>&1

該行會在週一至週五的 09:30 執行備份腳本,並將 stdout 與 stderr 附加到記錄檔中。請先手動測試指令,在非正式環境中部署,確認排程器的時區後,再正式上線。

部署前確認目標排程器

有些代管的排程器在標準的五個欄位之外,還會加上秒數、年份、問號或廠商專屬語法,因此請先確認你的目標接受標準的五欄 cron 後再部署。Cronie 的實作記載於 cronie-crond/cronie crontab(5),是多數現代 Linux 發行版遵循的參考實作,且完全接受產生器所產生的語法。如果你是部署到一個需要六欄 Quartz 運算式的代管平台,請改用 Quartz 專用的產生器,而不是硬把五欄的輸出塞進需要秒數欄位的欄位中。

想進一步了解,請參閱 Basic Linux Commands: 13 Safe Templates to Copy。

想進一步了解,請參閱 How to Create an Empty File in Linux Step by Step。