Cron式→systemdタイマー変換ツール

cron式(分 時 日 月 曜日)をsystemdタイマーのOnCalendar=構文に変換する無料ツール。日と曜日を同時指定した場合のOR条件の注意も警告表示し、Docker/Kubernetes環境でのcron移行に便利です。

cronフィールドとsystemdコンポーネントの対応表

cron式の5つのフィールドは、systemdのOnCalendar=構文では以下のように対応します。

位置 cronフィールド systemdでの対応箇所
1 時刻部分の分(HH:MM:SS の MM)
2 時刻部分の時(HH:MM:SS の HH)
3 日(日付) 日付部分の日(年-月-日 の 日)
4 日付部分の月(年-月-日 の 月)
5 曜日 曜日プレフィックス(例: Mon、Mon..Fri)

cronに秒フィールドはないため、systemd側の秒は常に「00」になります。また日付・曜日ともに無制限(*)の場合、systemd側の年-月-日部分は省略できます。

cronの曜日番号とsystemdの曜日略称の対応表

cronでは曜日を0〜7の数値で表しますが、systemdでは英語の曜日略称を使います。

cronの曜日番号 systemdの曜日略称
0 (7) Sun
1 Mon
2 Tue
3 Wed
4 Thu
5 Fri
6 Sat

よくある変換例

cron式 OnCalendar= 意味
* * * * * OnCalendar=*-*-* *:*:00 毎分実行します(cronの「* * * * *」相当)。
*/15 * * * * OnCalendar=*:00/15:00 15分ごとに実行します。
0 9 * * 1-5 OnCalendar=Mon..Fri 09:00:00 平日(月〜金)の9時0分に実行します。
0 0 1 * * OnCalendar=*-*-01 00:00:00 毎月1日の0時0分に実行します。
0 0 1 1 * OnCalendar=*-01-01 00:00:00 毎年1月1日の0時0分に実行します。
0 0 1 * 1 OnCalendar=Mon *-*-01 00:00:00 日(1日)と曜日(月曜日)の両方を指定した例。cronではOR条件(どちらか一方で実行)ですが、systemdではAND条件(両方を満たす日のみ実行)になるため、変換結果は元のcron式より実行頻度が少なくなる点に注意してください。

日(日付)と曜日の両方を「*」以外に制限したcron式は、systemdのOnCalendar構文では正確に変換できません(cronはOR条件、systemdはAND条件のため)。このようなケースでは、2つの別々のsystemdタイマーに分割することを検討してください。

Tips

  • 日(日付)と曜日の両方を「*」以外に指定すると、cronのOR条件をsystemdのAND条件では正確に表現できません。この場合は変換結果の警告を確認し、必要なら2つのタイマーに分割してください。
  • Alpine LinuxベースのDockerイメージなど、一部の最小構成コンテナにはcronデーモン自体が含まれていないことがあり、systemdタイマーへの移行が有効な代替手段になります。
  • 生成されたOnCalendar行は「systemd-analyze calendar」コマンドに渡すことでも構文チェックでき、次回実行予定時刻まで確認できます。
  • systemdタイマーは.timerユニットと、実際の処理を書く.serviceユニットの2ファイルセットで構成される点がcrontabの1行設定と異なります。
  • 曜日と日付を同時に使わない単純なスケジュール(毎時・毎日・毎週など)であれば、この変換は常に正確に一致します。

よくある質問

OnCalendar=は「曜日 年-月-日 時:分:秒」の形式で指定します(曜日と年-月-日は省略可能)。「*」は「制限なし(すべて一致)」、「..」は範囲、「/」は間隔、「,」は列挙を表します。例えば「Mon..Fri 09:00:00」は平日の9時ちょうどを意味します。

systemdタイマーはジャーナル(journalctl)による実行ログの一元管理、依存関係のあるサービスの起動待ち、実行失敗時の自動リトライ設定などcron単体にはない機能を持ちます。またDocker/Kubernetes環境ではベースイメージが軽量化のためcronデーモンを含まないことが増えており、systemdベースのホストではタイマーへの移行がその代替になります。

Vixie cronの仕様では、日と曜日の両方が「*」以外に制限されている場合「どちらか一方に一致すればよい」というOR条件になります。一方systemdのOnCalendar構文では曜日指定と日付指定は常にAND条件(両方一致が必要)です。そのため本ツールはこのケースを検出すると警告を表示し、変換結果が元のcron式より狭い条件(実行頻度が少ない)になっている可能性を伝えます。

単純なスケジュール(曜日と日付を同時に使わないもの)であれば正確に変換されます。ただし上記のOR条件の警告が出た場合は、意図した頻度と異なる可能性があるため、本番投入前に「systemd-analyze calendar」コマンドで次回実行予定時刻を確認することを推奨します。

標準的な5フィールドのcron式に秒フィールドは含まれないため、本ツールが出力するOnCalendar行の秒部分は常に「00」になります。systemdのOnCalendar構文自体は秒の指定にも対応していますが、cronからの変換では使用しません。
ツールくん

余談ですが ― cronからsystemdタイマーへ

systemdはLinuxの起動処理を管理する初期化システムとして2010年頃に登場して以来、多くのディストリビューションの標準になりました。その一部であるsystemdタイマーは、cronと同様に定期実行の仕組みを提供しますが、依存関係の解決・実行ログの一元管理(journalctl)・失敗時のリトライ設定など、cronにはなかった機能を備えています。

一方でDockerやKubernetesのようなコンテナ環境では、イメージサイズを軽量に保つためにcronデーモンをあえて含めないベースイメージが増えています。こうした環境でジョブの定期実行を行う場合、Kubernetes CronJobのようなオーケストレーター側の仕組みを使うか、ホストがsystemdベースであればsystemdタイマーに委ねるのが現実的な選択肢になります。

OnCalendar=構文はcronの5フィールドよりも表現力が高く、年単位の指定や秒単位の精度にも対応していますが、その表現力の違いゆえに一部のcron式(日と曜日を同時に制限したOR条件)は単純な変換では意味が変わってしまいます。本ツールがこの点を明示的に警告するのは、移行時に気づきにくい落とし穴を早期に発見してもらうためです。