cron 式の解説ツール
あらゆる cron 式を解説 — Vixie、Quartz、EventBridge、Jenkins。任意のタイムゾーンで次回実行を一覧し、落とし穴を指摘します。
Vixie cron として解釈しました。
この式の意味
00:00 に実行します。 対象日は 13 日、または 金曜日。
フィールドごとの内訳
| フィールド | 記述 | 一致する値 |
|---|---|---|
| 分 | 0 | 0 |
| 時 | 0 | 0 |
| 日 | 13 | 13 |
| 月 | * | すべての値 |
| 曜日 | 5 | 金曜日 |
注意すべき点
- 日付と曜日の両方のフィールドが制限されているため、cron はどちらか一方に一致した時点で実行します。両方が同時に成り立つ必要はありません。13 と金曜日の組み合わせが「13 日の金曜日」ではなく「毎月 13 日と毎週金曜日」を意味するのは、このためです。
次回以降の実行
このツールの役割
cron 式を言葉であなたに読み返し、ジョブが動くどのタイムゾーンでも次に実際に発火する時刻を一覧し、式が示唆するが言わないものを名指しします。その最後の部分が要点です: cron 式は、エラーを生むふうに誤っていることは決してありません。誰かが気づくまで、静かに誤った日に動きます。
一つではなく四つの方言が理解されます。crontab が取る五フィールド形式、秒フィールドとカレンダー規則を持つ Quartz、末尾に年の付く AWS EventBridge、そしてハッシュを持つ Jenkins です。別の方言しか知らないツールに一つを貼り付けることが、複数あると人が最初に気づく方法です。
フィールドと、その数
古典的な式は五つのフィールドを持ち、空白で分けられ、固定の順です: 分・時・日・月・曜日。それぞれが「すべて」を意味するアスタリスク、数値、カンマで分けた一覧、ダッシュの範囲、スラッシュの刻みのいずれかです。月と曜日は三文字の名前で書け、ほぼ常に数字より分かりやすいです。
- アスタリスクはフィールドが取りうるすべての値を意味します。
- 9-17 のような範囲は 9 から 17 まで両端を含むすべての値を意味します。
- */15 のような刻みはフィールドの下端から数えて 15 個ごとの値を意味します。9-17/2 は範囲の中で刻み、5/15 は 5 から上端まで刻みます。
- 0,30 のような一覧はまさにそれらの値を意味します。
- 13-13 のような退化した範囲は単に 13 です — これを誤ってアスタリスクとして扱うライブラリがあります。
六つ目のフィールドが方言の分かれ目です。Quartz はそれを前に置いて秒として読み、EventBridge は末尾に置いて年として読みます。だから六つの素のフィールドは本当に曖昧で、このツールは黙って選ぶのではなくどう読んだかを言います。式を cron(...) — EventBridge 自身の構文 — で囲むとそれが決着します。
マクロは略記です: @hourly、@daily、@midnight、@weekly、@monthly、@yearly、@annually。ふつうの式に展開され、ツールがそれを示します。@reboot は仲間外れで、まったくスケジュールではありません。
二つの日フィールドと、「かつ」に見える「または」
日付は二つの異なる方法で選べ — 日によって、曜日によって — cron は両方のフィールドを持ちます。両方が制限されているとき、ジョブはどちらか一方が一致すると動きます。両方ではありません。
だから 0 0 13 * 5 は 13 日の金曜日ではありません。毎月 13 日と、毎週金曜日です: 一つや二つではなく年に約 64 日です。式は連言に見えて選言のように振る舞い、何もエラーを報告せず、ジョブは単に意図より頻繁に動きます。
その規則には、より奇妙な後半があり、ほとんど誰も知らないものです。cron は日フィールドが制限されているかを調べません。フィールドの最初の文字がアスタリスクかを調べます。だから */14 のような刻みは、フィールドを 1 日・15 日・29 日に制限するのにアスタリスクとして数えられ — その存在が二つの日フィールドを「または」から「かつ」に戻します。等しく制限されて見える二つの式が、まったく異なるふうに振る舞い、このツールはどちらの規則が効いているかを報告します。
Quartz と EventBridge は、両方のフィールドが何かを言うのを許さないことで、問い全体を避けます: どちらか一つがちょうど疑問符でなければならず、それは「特定の値なし、もう一方のフィールドが決める」を意味します。
自分のフィールドを割り切らない刻み
刻みは間隔であるかのように書かれ、フィールドの一周期の中ではそうです。境界をまたぐとたいていそうではありません。
時フィールドの */7 は 0・7・14・21 時を意味します。21 の後フィールドが尽きるので、次の実行は翌日の 0 時 — 7 時間後ではなく 3 時間後 — です。すべての周期が一つの短い間隔で終わり、分の */7 (56 の後に 4 分の間隔) や、範囲を均等に割り切らないほかのどんな刻みでも同じことが起きます。分の */15 と時の */6 は安全です。人が手を伸ばす数のほとんどはそうではありません。
これは、刻みが作業を間隔をあけるために選ばれるとき重要です。*/7 時のジョブは 7 時間ごとには動かず、7 に合わせたレート制限は 1 日に一度破られます。
曜日は場所によって異なる番号付け
Vixie cron は日を 0 から 7 まで、日曜日を両端に置いて番号付けるので、0 と 7 は同じ日で 1 は月曜日です。Quartz と EventBridge は 1 から 7 まで、日曜日を 1 に置いて番号付けるので、そこでは 1 が日曜日で 2 が月曜日です。
だから Quartz の設定から crontab にコピーした式は 1 日早く動き、どこでも何も文句を言いません。どちらの綴りも両方のシステムで有効な数値だからです。三文字の名前 — MON、FRI — はどこでも同じ日を意味し、単純な防御です。
夏時間: 年に二つの朝
cron デーモンは瞬間をスケジュールしません。毎分ローカルの壁時計を見て、式が一致するかを問います。年に二度、その時計は行儀のよい並びではありません。
前に飛ぶとき、1 時間分の読み取りが決して起きません。02:30 に設定されたジョブは、その日 02:30 を持ちません。後ろに戻るとき、1 時間分の読み取りが二度起き、01:30 に設定されたジョブはそれを二つ持ちます。
Vixie cron はここで二種類のジョブを区別し、その区別はどのジョブが影響を受けるかを決めるので知る価値があります。壁時計の時刻に固定されたジョブ — 固定の時と固定の分 — は、どちらの場合もちょうど一度動きます: 前への飛躍の後すぐ動き、後ろへの後 cron はそれを繰り返さないよう配慮します。時や分にアスタリスクを持つジョブは間隔ジョブで、単に時計に従います: 春には 1 時間分の実行を失い、秋には 1 時間分を繰り返します。
だから毎時のバックアップは本当に年に一晩二度動き、02:30 の夜次のジョブは本当に別の日に異例の瞬間に動きます。このツールは選んだゾーンの次の 12 か月をあなたの式に対して確認し、二つのどちらが当てはまるかを日付とともに言います。
確かな出口は、ジョブを UTC で、あるいは切り替わりの落ちないローカルの 01:00〜03:00 の外でスケジュールすることです。
ジョブが実際にどの時計にあるか
crontab はマシンのローカルゾーン、あるいはファイルの先頭で CRON_TZ や TZ が言うものの上で動きます。それは式を読む人のゾーンであることはめったになく、だからここのタイムゾーンはブラウザのではなく設定です。
Kubernetes の CronJob はまた別です: マニフェストが timeZone フィールドを設定しない限り、ノード自身の時計が何を言おうと、スケジュールを UTC として読みます。ローカルの営業時間向けに書かれ、そのフィールドなしにデプロイされたスケジュールは、UTC の外のどこでも一日の誤った時刻に動き — 季節とともに変わらず、それはジョブによってバグか安堵かのどちらかです。
Jenkins と H
Jenkins はほかのどの方言も持たないトークンを加えます: H で、ランダムに見えてそうではありません。Jenkins はジョブの名前をフィールドの範囲内の固定値にハッシュするので、ジョブは毎日同じ時刻 — 自分の時刻 — に動き、一方 H * * * * と書かれた 100 のジョブは、皆が同じ分に始まるのではなく 1 時間にわたって均等に散らばります。
値がジョブ名から来て、ジョブ名が式の一部でないので、どのツールも正確な時刻を計算できません。これはすべての H をその範囲の下端に解決し、そう言います: スケジュールの形 — どれくらいの頻度で、どの日に — は正確で、各期間の中のオフセットだけが代役です。
Jenkins はマクロも再定義します。その @daily は @midnight で、それは真夜中ではなく、その日の最初の 3 時間のどこかにあるハッシュされた分です。
cron がしないこと
- 追いつきません。実行が予定されていたときにマシンが眠っていたりデーモンが落ちていたりしたら、その実行は後で起きません — 単に見逃されます。anacron がまさにこのために存在し、別のプログラムです。
- 重なる実行を止めません。ジョブが間隔より長くかかると、次のものがとにかく始まり、しばらくすると複数になります。ロックファイルがふつうの答えです。
- 古典的な形には秒の概念がありません。最も細かい分解能は 1 分で、それより速いものは Quartz、systemd、あるいはジョブの中のループが要ります。
- @reboot はスケジュールではありません。デーモンの起動時に一度動くので次の実行がなく、決して再起動しないマシンではまったく動きません。
- EventBridge の rate 式はルールが作られたときから数え、その瞬間は式にないので、どのツールも次にいつ発火するか言えません。
よくある質問
- 月の第 1 月曜日にジョブを動かすにはどうしますか?
- 素の cron 式ではできません — それは二つの日フィールドの間の「かつ」を要し、cron は「または」を与えます。標準の回避策は 0 0 1-7 * * をスケジュールし、コマンド自身に曜日を確認させることです。Quartz と EventBridge はそれを直接、0 0 12 ? * MON#1 として表せます。
- 0 0 13 * 5 がなぜこれほど頻繁に動くのですか?
- 13 日の金曜日ではなく、13 日または毎週金曜日を意味するからです。両方の日フィールドが制限されどちらもアスタリスクで始まらないとき、cron はどちらか一方が一致するとジョブを動かします。古典的な方言に「かつ」を書く術はありません。
- */5 と 0-59/5 の違いは何ですか?
- 分フィールドには何もありません: どちらも 0・5・10 などを与えます。違いは二つの日フィールドに現れ、そこで cron はフィールドがアスタリスクで始まるかを見て「かつ」と「または」を決めます — だから */5 と 0-59/5 は同じ日を選びますが、もう一方の日フィールドとは異なるふうに組み合わさります。
- 時計が戻るとき私のジョブは二度動きますか?
- 時や分にアスタリスクを持つなら、はい: 時計に従い、その 1 時間が二度起きます。固定の時と分を持つなら、いいえ — Vixie cron はそうしたジョブを一度動かします。findings パネルがあなたのがどちらの場合かを、当てはまる日付とともに言います。
- cron 式はどのタイムゾーンを使いますか?
- crontab で CRON_TZ か TZ が設定されない限り、マシンのものです。Kubernetes の CronJob は、マニフェストが timeZone を設定しない限り UTC を使います。ゾーンは式の一部でないので、このツールはブラウザのを仮定するのではなくそれを求めます。
- 何かを 90 分ごとにスケジュールできますか?
- 一つの式としてはできません。各フィールドが独立に周回し、90 分は 1 時間に収まらないからです。ふつうの綴りは二つの式、0 0,3,6,9,12,15,18,21 * * * と 30 1,4,7,10,13,16,19,22 * * * で、合わせて 90 分ごとの実行を与えます。
- 私が貼り付けたものはサーバーに送られますか?
- いいえ。解析・説明・スケジュール計算の全体がブラウザ内で動きます。何もアップロードも記録もされず、ネットワーク接続なしで動きます。