クロン式ジェネレーター
視覚的にcronジョブのスケジュールを構築して理解します。
クイックプリセット
次の5回の実行
cron構文リファレンス
* · 任意の値
*/5 · 5単位ごと
1,15 · 値1と15で
1-5 · 1から5の範囲
フィールド: 分(0-59)、時(0-23)、月の日(1-31)、月(1-12)、曜日(0-6、0=日曜日)
cron 式の簡単な歴史
5フィールドの cron 式は 1975年5月に遡り、初期バージョンが AT&T Bell Laboratories から Research Unix Version 7 の一部として出荷されました。名前は Chronos、ギリシャの時間の擬人化を暗示しています。フォーマットはシンプルでした:/usr/lib/crontab の1行に空白で区切られた5つのフィールド(分、時、月の日、月、曜日)。Paul Vixie による1987年の Vixie cron リライトが事実上のモダン実装になりました。すべての主要な Linux ディストリビューションは Vixie 派生の cron を出荷し、Vixie はユーザーごとの crontab、環境変数サポート(MAILTO=、CRON_TZ=)、そして誰もが今日使用する @hourly / @daily / @reboot ショートカットマクロを追加しました。cron 式構文はその後、2つの経路に分かれました。Quartz Scheduler(Java、James House、1998;Apache および Terracotta に寄贈)は、先頭の秒フィールド、オプションの末尾の年フィールド、および L(最後)/W(平日)/#(n 番目の出現)演算子を追加し、AWS EventBridge(元は CloudWatch Events、2014)と Spring の @Scheduled アノテーションが後に採用した6フィールドの cron を生み出しました。Azure Functions(2016)が使用する NCronTab フォーマットは秒を最初に置きましたが5つの動作フィールドを維持しました。クラウド時代はその後、5フィールドの Vixie フォーマットを共通語として標準化しました:Kubernetes CronJobs(2016年に alpha 1.4、2021年に GA 1.21)はちょうど5フィールドを受け入れます、GitHub Actions(on.schedule.cron、2019)、GCP Cloud Scheduler(2018)、Vercel Cron Jobs(2022)も同様です。このツールが属するビジュアル cron ビルダーは2010-2015年頃に出現しました:crontab.guru(Christine Dodrill、2014)が最も引用される参照になり、cron-descriptor ライブラリ(Brady Holt、元は .NET、Java/Python/JS に移植)が、デコーダーとジェネレーターが依存する「平易な英語の cron」翻訳層のほとんどを動かしました。Bell Labs から半世紀後、同じ5つのフィールドが今でも世界の夜間バックアップをスケジュールしています。
cron 式の構造
- 5つのフィールド、空白で区切られています。順番に:
分 (0-59) 時 (0-23) 月の日 (1-31) 月 (1-12) 曜日 (0-6)。式0 9 * * 1は「分0、時9、任意の月の日、任意の月、曜日1(月曜)」を意味します、つまり毎週月曜日午前9:00です。月は1から始まる索引付け;0 0 1 0 *は無効です、なぜなら月0はないからです。 - 4つの演算子。
*はフィールドの範囲のすべての値に一致します。,は離散値をリストします:分フィールドの0,15,30,45。-は範囲を定義します:時フィールドの9-17は午前9時から午後5時をカバーします。/はステップを設定します:分の*/15は0、15、30、45 で発火します。これら4つの演算子は自由に組み合わせられます:*/15 8-18 * * 1-5は「8 時から18時の間、平日のみ15分ごと」を意味します。 - ショートカットマクロ。Vixie cron とほとんどのモダンパーサーは
@yearly(または@annually、0 0 1 1 *に等しい)、@monthly(0 0 1 * *)、@weekly(0 0 * * 0)、@daily(または@midnight、0 0 * * *)、@hourly(0 * * * *)、および特別な@reboot(cron デーモンが起動すると1度実行)を受け入れます。クラウドプラットフォームは異なります:GitHub Actions と Vercel はマクロを拒否します。 - ステップの落とし穴。範囲 a-b のフィールドの
*/Nは a、a+N、a+2N、... で発火し、必ずしも壁時計時間の N 単位ごとではありません。分フィールドの*/7は0、7、14、21、28、35、42、49、56 で発火し、次の時の頭で0に戻り、4分のギャップを生じます。標準 cron でラッパーなしでの真の7分ごとのスケジューリングは不可能です。 - OR のトラップ(月の日 vs 曜日)。両方のフィールドが制限されている場合、標準 Unix cron はどちらかが一致したときに発火し、両方ではありません。
0 0 1 * 1は「1日に該当する月曜」を意味しません、「毎月1日、加えて毎月曜」を意味します。crontab(5)マニュアルページは明示的です。Quartz、AWS EventBridge、systemd タイマーはすべて「最初の月曜」をきれいに表現します;Vixie cron はラッパーが必要です。 - 曜日の番号付けは異なります。Linux/Vixie、GitHub Actions、GCP Cloud Scheduler、Kubernetes、Azure NCronTab、Spring 5.3+ はすべて 日曜 = 0 を使用します(Vixie は7も受け入れます)。Quartz と AWS EventBridge は 日曜 = 1 を使用します。
0 0 * * 1はしたがって Linux では「毎月曜」を意味しますが Quartz の下では「毎日曜」を意味します。ポータビリティが重要な場合は3文字名(MON、TUE)を使用してください。
式が使われる場所
- Linux / macOS cron。
crontab -eにコマンドを続けて貼り付けます。名前(MON、JAN)とショートカットマクロ(@hourly、@daily、@reboot)が受け入れられます。サーバーが UTC にあるがローカル時間でスケジュールしたい場合は、crontab の先頭にCRON_TZ=America/New_Yorkを設定します。 - Kubernetes CronJob。
spec.scheduleを5フィールドの式に設定します。spec.timeZone(1.27 で GA、2023年3月)は「Europe/Paris」のような IANA ゾーンを受け取ります。スケジュール文字列にTZ=を埋め込むことは 1.29 以降拒否されます。停止後のキャッチアップ動作を制御するにはspec.startingDeadlineSecondsを使用します。 - GitHub Actions。
on.schedule.cronにドロップします。スケジュールは UTC で実行され、最短のケイデンスは5分(それより細かいものは静かに丸められます)、パブリックリポジトリのスケジュールされたワークフローはリポジトリの非アクティブ60日後に自動無効化されます。YAML 内の cron 文字列は、先頭の*でのパーサー混乱を避けるために引用符で囲む必要があります。 - AWS EventBridge / EventBridge Scheduler。6フィールドを使用します:
cron(min hr dom mon dow yr)。月の日または曜日のいずれかに?が必要です(両方のリテラルではない)。Quartz スタイルのL(最後)、W(平日)、#(n 番目の出現)演算子はすべてここで動作します。Scheduler 製品(2022)はワンショットタイマー用に別のat()式を追加しました。 - GCP Cloud Scheduler。Linux と一致する5フィールド構文。
timeZoneプロパティは IANA ゾーンを受け取ります。Cloud Pub/Sub または HTTP ターゲットと組み合わせます。retryConfigは一時的な失敗を処理します;デフォルトはリトライなしで、これは少なくとも1回のセマンティクスを期待するエンジニアを驚かせます。 - Vercel Cron Jobs。
vercel.jsonの5フィールド構文。両方の日フィールドを同時に設定することはできません。Hobby プランは日次にケイデンスを制限します;Pro プランは時間単位を許可します。関数パスへの HTTP GET をトリガーし、これはトリガーがリトライする場合、関数は冪等でなければならないことを意味します。
標準、方言、マイルストーン
- AT&T Bell Labs cron(1975年5月)。オリジナル。5フィールド、ユーザーごとの crontab なし、
/usr/lib/crontabから実行。Research Unix Version 7 の一部。すべての現代の変種が拡張する空白区切り文法。 - Vixie cron(Paul Vixie、1987)。誰もが実行しているリライト。ユーザーごとの crontabs、
@hourly/@daily/@rebootマクロ、名前エイリアス(MON、JAN)、およびMAILTO/CRON_TZ環境変数を追加しました。ほとんどの Linux ディストリビューションは Vixie cron、dcron、または cronie(Vixie の Red Hat フォーク)を出荷します。 - Quartz Scheduler(James House、1998)。6フィールドの cron(先頭の秒付き)と
L/W/#演算子を導入した Java ライブラリ。Apache とその後 Terracotta に寄贈されました。Spring の@Scheduledアノテーションは Quartz セマンティクスを埋め込みます;Spring 5.3+ は曜日を Quartz の「日曜=1」から Linux の「日曜=0」に物議をかもして切り替えたので、同じ文字列が異なるバージョンで異なる日を意味するようになりました。 - systemd タイマー(Lennart Poettering、2010)。ほとんどのモダン Linux ディストリビューションで cron を置き換えます。異なる文法(
OnCalendar=Mon..Fri 09:00)を使用し、カレンダーとモノトニックの両方のスケジュールをサポートし、journaldにログを記録し、サービス依存性を宣言でき、systemd-analyze calendarで検証し、Persistent=trueを介して cron 風の精度を anacron 風のキャッチアップと組み合わせます。 - NCronTab(Azure Functions、2016)。秒を最初にした6フィールド:
{second} {minute} {hour} {day} {month} {day-of-week}。年フィールドなし。デフォルトのタイムゾーンは UTC;Linux App Service プランでWEBSITE_TIME_ZONEアプリ設定でオーバーライドします。 - AWS EventBridge cron 構文。年を最後にした6フィールド:
cron(min hr dom mon dow yr)。使用されない dom/dow のいずれかにプレースホルダーとしてリテラル?が必要です。QuartzL、W、#をサポートします。元は CloudWatch Events(2014)、2019年に EventBridge に名前変更。 - 5対6フィールドの移植性問題。5フィールドの Linux 式を Quartz や Spring に貼り付けると「cron expression must consist of 6 fields」エラーが発生します;6フィールドの式を Linux cron に貼り付けると、Linux が秒列を分として読み取るため「bad day-of-week」が発生します。逆のミスは、静かに解析されて間違ったスケジュールで実行される可能性があるため、より危険です。
- Jenkins
H(ハッシュ)拡張。Jenkins は標準 cron をHで拡張し、同じ瞬間に各ジョブを実行する代わりに、ジョブごとに安定したがランダム化された値を選択します。H * * * *は「毎時、ただし各ジョブで異なる分」を意味し、多くのジョブが分0でスケジュールするときの「サンダリングハード」問題を防ぎます。
その他のよくある質問
5フィールドは6または7フィールドと同じですか?
いいえ。古典的な POSIX 形式は5フィールド(分、時、月の日、月、曜日)です。Quartz と Spring は先頭の秒列を追加することで6フィールドを使用し、Quartz はオプションの7番目の年フィールドを受け入れます。AWS EventBridge は常に年で終わる6フィールドを使用します(cron(min hr dom mon dow yr))。5フィールドの式を Quartz または Spring に貼り付けると構文エラーが発生します;6フィールドの式を Linux に貼り付けると、フィールドを静かに誤解釈します。
cron が表現できる最小の間隔は何ですか?
標準 Unix cron で1分ごと(* * * * *)。組み込みの秒フィールドはありません。サブ分のケイデンスが必要な場合は Quartz や NCronTab などのスケジューラがそれを追加し、systemd タイマーは OnUnitActiveSec=30s を使用できます。GitHub Actions は最短のケイデンスを5分にキャップし、EventBridge はスケジュールされた時刻の60秒ウィンドウ内に発火するので、cron をハードリアルタイムの精度に頼らないでください。
月の最終日にジョブを実行するにはどうすればよいですか?
標準の5フィールド cron にはネイティブの「月の最終日」演算子はありません。Quartz と AWS EventBridge は月の日フィールドで L をサポートします:0 0 L * ? は最終日の深夜に発火します。素の Linux cron では、通常の回避策は候補日に毎日スケジュールしてコマンドをゲートすることです:0 0 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /path/to/script。systemd タイマーは OnCalendar=*-*-* 00:00:00 で直接表現します。
なぜ私の cron ジョブは予期したときに実行されなかったのですか?
通常の容疑者、順番に:(1) サーバーが想定とは異なるタイムゾーンにある(date で確認);(2) PATH がインタラクティブシェルのものとは異なるため、コマンドはプロンプトで動作するが cron 下では失敗する(絶対パスを使用);(3) 出力が電子メールに送られたが見逃した(MAILTO="" を設定するか、ログファイルにリダイレクト);(4) cron デーモンが実行されていない(systemctl status cron);(5) OR トラップ(上記参照)が意図しない余分な日に発火している。
cron、anacron、systemd タイマーの違いは何ですか?
Cron はシステムがスケジュールされた時刻に稼働していることを期待し、ダウンタイム中に発生するジョブを静かにスキップします:常時稼働サーバーには良いが、ラップトップには悪い。Anacron はジョブごとの最終実行タイムスタンプを追跡し、再起動後に見逃したジョブをキャッチアップしますが、分単位ではなく日単位の精度というコストがかかります。systemd タイマーはほとんどのモダン Linux ディストリビューションで cron を置き換えます:カレンダーとモノトニックの両方のスケジュールをサポートし、journald にログを記録し、サービス依存性を宣言でき、Persistent=true を使用して cron 風の精度を anacron 風のキャッチアップと組み合わせます。
タイムゾーンと夏時間は cron にどのように影響しますか?
ほとんどの cron デーモンはシステムのタイムゾーンでスケジュールを解釈します。クラウドサーバーではこれは通常 UTC を意味するので、0 9 * * * は午前9時 UTC で発火し、午前9時ローカルではありません。Linux crontab で CRON_TZ=America/New_York を設定します;Kubernetes は spec.timeZone を使用します;AWS、GCP、Vercel はそれぞれ明示的な IANA ゾーンを受け取ります。春の前進中、スキップされた時間内にスケジュールされたジョブは Vixie cron によって直後に実行されますが、AWS EventBridge では完全にスキップされます。最も安全なパターンは、cron を UTC に残してジョブ内で変換することです。