systemd タイマー / cron 変換ツール | cron ↔ OnCalendar 双方向変換と次回 5 件プレビューで .timer 移行を 1 画面に集約
cron で書いた定期実行スケジュールを systemd の .timer ユニットに置き換えたい、もしくは逆に OnCalendar 式を crontab 行に戻したい、というシーンで使う変換ツール。双方向に round-trip でき、次の 5 回の起動時刻も同時にプレビューするので、構文ミスや意図と違うスケジュールに気づける。
💡 このツールについて
systemd 採用ディストロでは長らく crond と systemd-timer が併存している。ホストごとに方針が違うと、cron 行を .timer ユニットに書き換える機会は意外と多い。OnCalendar の [DOW] Y-M-D H:M[:S] 書式は cron と並びが違い、曜日が前にきて月日と時刻がコロンで区切られる点で、ぱっと見の対応が取りづらい。
このツールは *, */N, A-B, A,B,C, JAN-DEC, MON-FRI を含む POSIX 系の cron を OnCalendar に書き換え、逆方向では .. range や 0/N step、先頭 DOW を解釈する。RandomizedDelaySec は cron に対応する要素がないので、変換時に自動で剥がして警告枠に出す。秒指定 (6 フィールド cron) も systemd 側でしか有効化できないことを明示する。
タイムゾーンは UTC・ブラウザローカル・主要 7 地域から選べ、選択した zone で次回 5 件を計算する。サーバーが UTC で動いているのに開発者の手元の cron は JST 表記、というよくあるズレを 1 画面で確認できる。
🧐 よくある質問
Q. 6 フィールド cron (秒指定) はどう扱う? A. 先頭フィールドを秒として OnCalendar に書き出すが、POSIX cron 側では再現できないため警告を出す。Quartz 形式の cron スケジューラを使うときの参考にする想定。
Q. @daily や @reboot のショートカットは?
A. 現状は通常の 5 / 6 フィールド書式のみ対応。@daily は 0 0 * * * と等価なのでそちらで入力する。@reboot は systemd では OnBootSec= などの別の Timer 指定子に相当し、本ツールの変換対象外。
Q. Mon..Fri のような曜日 range は systemd→cron でも維持される?
A. OnCalendar 側で Mon..Fri を解釈して [1,2,3,4,5] に展開し、crontab 行では 1,2,3,4,5 の形で書き出す。cron に range 書式 MON-FRI で戻したい場合は手動で書き換える。
Q. RandomizedDelaySec を残したまま cron に変換できる?
A. cron 側には RandomizedDelaySec 相当の機能がないため、変換時に自動で剥がす。バッチをずらしたい場合は cron 行内で sleep $((RANDOM % 60)) を併用するなどの対応が必要。
Q. 次回 5 件のタイムゾーンが UTC のままで開発機の JST と合わない
A. タイムゾーン select で Asia/Tokyo (JST) か「ブラウザのタイムゾーン」を選ぶと、その zone での次回起動時刻を再計算する。.timer ユニット内で Timezone= を指定したい場合は別途追記する。
Q. パース失敗時に何が表示される?
A. 入力欄の下の赤い警告枠に具体的なフィールド名 (Invalid value:、Date must be Y-M-D など) が出る。出力欄は -- のまま動かない。
📚 豆知識
systemd-timer は 2010 年前後に systemd v183 付近で導入された比較的新しい仕組みで、cron デーモンを置き換える目的というより「サービスを実行するための補助スケジューラ」として設計された。.timer ユニットは対応する .service ユニットを Unit= で指して起動するため、cron のように「コマンドをスケジューラに直接書く」スタイルではなく、サービス単位の管理に馴染みやすい。逆に言えば、シェルスクリプト 1 行を回したいだけのケースでは .service を 1 個増やすコストが負担で、運用側の好みが分かれる部分でもある。
OnCalendar の式は ISO 8601 風の Year-Month-Day Hour:Minute:Second を基にしているが、wildcard * や range A..B や step 0/N は systemd 独自の拡張で、ISO 8601 そのものではない。慣れていないと *-*-* 00/15:00 と書いて「15 分ごとを意図したのに 15 分ぶん遅延しただけ」になる罠もある (正しくは *-*-* *:0/15)。