世界を動かす技術を、日本語で。

systemdタイマーを愛する

概要

  • cron の代替として systemd timer が推奨される理由
  • systemd timerの 基本的な使い方 と設定例
  • cronとの違い やsystemd timerの利点
  • スケジュール表現 と実用的な活用例
  • タイマー管理コマンドによる 全体把握 の方法

systemd timerをもっと愛そう

  • cron job は長年使われてきたが、2026年現在は systemd timer がより優れた選択肢
  • systemd timer は、他のunit(多くは.service)を スケジュール実行 する仕組み
    • cronのような表現もサポートし、移行も容易
  • systemd timerの主な利点
    • $PATHの曖昧さ がなく、実行環境が明確
    • 標準出力・標準エラー がsystemd journalに記録され、 履歴追跡 が容易
    • スケジュール表現 が人間に分かりやすい
  • cronの「01,31 04,05 1-15 1,6 *」のような難解な表現より、systemd timerの方が直感的

systemd timerの基本

  • まず、 実行対象のservice unit (例:roulette.service)を作成
    • 例:
      [Unit]
      Description=1 in 10 chance to break your chains
      [Service]
      ExecStart=/usr/bin/env bash -c '[[ $(($RANDOM % 10)) == 0 ]] && systemctl poweroff || echo LIVE ANOTHER DAY'
      
  • 条件付き実行には ExecCondition= を活用
    • より明確な意図表現とjournalの記録
  • timer unit (例:roulette.timer)を同じファイル名で作成
    • 例:
      [Unit]
      Description=impending destruction
      [Timer]
      OnCalendar=10:00
      [Install]
      WantedBy=timers.target
      
  • timerを start/enable することで、指定時間にserviceが実行される
    • systemctl start roulette.timerでタイマー起動
    • systemctl enable roulette.timerでブート時に自動起動

systemd timerの特徴とTips

  • ExecStart= はシェルコマンドとして直接解釈されないため、 絶対パス指定/usr/bin/envの活用が推奨
  • 環境変数 はデフォルトで引き継がれないため、必要に応じて明示的に設定
  • [Install]セクション がないとenableできない点に注意
  • systemctl startで.timerを起動しても、即座に.serviceは実行されない(スケジュール待機状態)

スケジュール表現と応用例

  • systemd.time(7) マニュアル参照推奨
  • systemd-analyze calendar コマンドでスケジュール表現のバリデーション・解説が可能
    • 例: systemd-analyze calendar '*-*-* *:*:*'
  • カレンダー式相対時間式 の2種類
    • 例:OnCalendar=dailyOnBootSec=1h OnUnitActiveSec=1h
  • 相対時間 は「起動から1時間後、以降は1時間ごと」など、実運用で便利
  • cronのような「毎時○分」よりも、「前回実行から○分後」の方が合理的なケースも多い

タイマーの全体管理

  • systemctl list-timers全タイマーの一覧表示
    • 次回実行時刻、経過時間、関連するserviceなどを一目で把握可能
  • タイマーの 全体像把握 やデバッグに非常に便利
  • --allオプションで非アクティブなタイマーも表示

systemd timerのさらなる利点

  • OnFailure=Restart= など、systemd独自の高度なオプション活用が可能
  • journalctl で実行履歴・エラー確認も容易
  • cron からの移行も段階的に可能で、既存の運用にも馴染みやすい
  • 単一コマンド でタイマー管理・状態確認ができ、保守性向上

systemd timer は、従来のcronの課題を解決しつつ、より柔軟かつ強力なスケジューリングを実現 Linux運用 における新たな標準として、積極的な活用が推奨

Hackerたちの意見

cronieからsystemdタイマーに移行したのは、システムの起動時間に強いからなんだ。バックアップの戦略として、毎日決まった時間にborgアーカイブのエントリーを作成するようにしてる。cronieだと、スケジュールされた時間にシステムが動いてないとダメなんだけど、systemdタイマーはそれを許容して、システムが利用可能になったらすぐにサービスを実行してくれるんだ。ちなみに、これがバックアップ自動化のためのリポジトリだよ: https://github.com/gchamon/borg-automated-backups

cronieには「anacron」っていう仕組みがあって、これがcronによって毎時呼ばれるんだ(俺のシステムでは、/etc/cron.hourly/0anacron)。これによって、最も早いスケジュールが逃した場合でも、/etc/cron.{daily,weekly,monthly}のタスクを実行してくれる(設定可能なランダムな遅延付きで)。/etc/anacrontabを修正すれば、カスタムスケジュールを作成できるよ。ユーザー単位でこれをやるには、ユーザーのcrontabに「@hourly anacron -t /path/to/anacrontab -S /path/to/spooldir」みたいな感じで追加すればいいけど、俺は試したことないんだ。多くのcron実装にも似たような仕組みがあるよ。

ごめん、「tolates」って言葉をググってみたけど、意味がわからない定義が見つからなかった。> システムが利用可能になるとすぐにサービスを実行します。cronには@rebootオプションがあって、いくつかのスクリプトで使ってるけど、すごくうまくいってるよ。

cronieではシステムがスケジュールされた時間に動いてないとダメだけど、systemdタイマーはこれを許容して、システムが利用可能になったらすぐにサービスを実行するよ。Cronieには@rebootメタトリガーがないの?

タイマーは任意の単位で動作できるから、意外と柔軟なんだよね。俺のサーバーには、毎朝ランダムな開始時間で「restic backup」、「restic prune」、「restic forget」のバックアップサイクルを実行するbackup.targetを起動するタイマーがある。実際のrestic-*ユニットはPodman Quadletsだから、サーバーに何があっても、PodmanとSystemdがインストールされてれば動くんだ。ただ、タイマーは定期的に使うにはちょっと扱いづらいシステムdユニットの一つだと思う。分割されてる理由は分かるけど、時々はスクリプトを実行するだけのファイルを作りたいだけなんだよね。

なんでバックアップの時間をランダムにしてるの?

systemdユニットには、上に抽象化のレイヤーが必要な気がする。手動でファイルを編集するのではなく、ツールがやってくれるような、何か宣言的なCLIとか。今のLLMの時代ではあまり関係ないかもしれないけど、毎回ちょっと面倒に感じるんだよね。

Canonのプリンターを使ってるんだけど、しばらく放置すると印刷ノズルが詰まっちゃうかもしれないから、claudeに毎週犬の写真を印刷するsystemdスクリプトを設定してもらったんだ。プリンターにストレスをかけるために、CMYKのスペクトルが十分あることを確認してる。月曜日にデスクに座ってると、突然プリンターから写真が出てくるのはいいサプライズだね :)

プリンターにアルバムやカレンダーからランダムな画像を印刷するモードがあったらいいのに。毎日インクをスポンジに無駄に吸わせるよりはさ。何もなければ、子供の高校の科学フェアのプロジェクトのアイデアになるかもね。

お父さんはDeskjet 720かなんかを持ってたんだけど、彼が亡くなった後、数年間使わずに電源も切ったままだった。カラー印刷が必要になったときに、電源をつないで印刷したら、最初は1/5ページくらいまで色が戻るのに時間がかかったけど、その後は20ページくらい問題なく印刷できたよ。

安いOKIのLEDカラープリンター(C322dnだと思う)を勧めようと思ったんだけど、残念ながら消費者市場から撤退しちゃったんだ :/ 色合いはすごくきれいで均一なんだけど、最大解像度が600dpiしかないのが残念。でも、トナーが乾かないのは、兄貴にとって重要な購入基準だったし、HPのインクジェットは何度も詰まったからね。

レーザープリンターは最高だよ。消耗品のコストだけでも元が取れるからね。

systemdのタイマーはあまり使ったことがないから反論はできないけど、> 曖昧な$PATH設定はcronスクリプトの実行を予測しにくくする。なんでそう思うの? crontabでPATHを設定できるじゃん。それが/etc/bashrcや~/.bashrc、~/.profile、~/.bash_profile、/etc/systemd/...などで設定されているよりも「予測しにくい」ってこと? > スケジューリングの文法を暗記しているとカッコいいかもしれないけど、1994年からLinuxを使ってるけど、私は暗記してないよ。でも幸運なことに、crontabにはコメントとしてプリントされてるからね:# 詳しくはcrontab(5)とcron(8)のマニュアルページを見てね。# # m h dom mon dow コマンド タイトルに合わせて数字を入れるだけだよ。他の不満もわかるけど、次にcronjobが必要になったら試してみるよ。

systemdの環境のいいところは、標準的でほぼ真っ白な状態だってこと。少なくとも私にとっては、Crontabの環境がsupervisordやsysvinitスクリプトの環境と全然違ってて、いつも困ってたから。systemdでは、実行されるユニットはトリガーに関係なく同じだから、ギャップがないんだ。それにはデフォルトの環境を知っておく必要があるけど、ほぼ完全にクリーンな環境で、シェルの影響も受けない。これがsystemdの利点だってことには同意するよ。

「タイトルに合わせて数字を入れるだけだよ。」っていうのは、彼らのポイントを公平に要約してないよ。文法にはコンマやスラッシュ、アスタリスク、組み合わせがあって、ランダム化が必要な場合はコマンド自体に入れなきゃいけないから、cronではできないんだ。(一部のcronはできるけど、一般的な機能じゃない。)非自明なcron仕様を書くのは簡単じゃないよ。

アプリケーションでcron式をサポートするって聞いてたけど、数字は言語の基本部分に過ぎないんだよね。誰かが「5,3/4 4-8,11 1 4,5,6,9-11 */2」みたいな意味不明なものを入力すると、彼らが何を言いたかったのかを逆に解析する楽しみがあるよ(実際に書いたこととは全然違うことが多い)。しかも、いろんなcron環境でサポートされている拡張機能もあるし(でも全部ではない)。systemdのタイマーの方がずっと管理しやすいと思う。長時間実行されるジョブが重複するかどうかをコントロールできたり、固定の時間枠ではなく開始から終了までの間にタスクを実行できるのは大きな改善だね。ある時、バックアップジョブがシンボリックリンクのループにハマって、cronがどんどんバックアップタスクを生成し続けて、どれも終わらなかったことがあった。CRONが独自の特別なPATHを持っているせいで、コマンドやスクリプトを書き直さなきゃいけなかったのも面倒だったけど、systemdのタイマーでも同じことがあるかも。でも、タイマーは手動で実行できるから、30秒後にトリガーするようにcrontabを更新して待つ必要がないのがいいよね。

1994年からLinuxを使ってる 同じく。今や私たちは古いと見なされて、無視される存在だね。新しい世代はタイマーを使ってて、何十年も私たちを支えてきたcronなんてどうでもいいって感じ。俺はcronを使ってるけど、LPやsystemdに対する一般的な態度は、LPやsystemdが私たちに対して持ってる態度とすごく似てる。

でも幸い、crontabにはコメントとしてプリントされてる それは確かだけど、大抵の人は番号付きのマニュアルセクションを知らないから、cronテーブルコマンドのドキュメントを見て、cronテーブルの設定ファイルは見ないんだよね。

変数の問題は、ファイル内の次のエントリにも適用されるから、その点を考慮する必要があることだね。タイマーのいいところは、すべての設定が自己完結していて、前のエントリに影響されないこと。標準の/10や似たようなcronの表現は、サーバーがたくさんあるときに「サンダリングハード」問題があるけど、Jenkinsのような一部のバリアントはH/10(Hはハッシュの略)を使って、時間をランダムにずらして同じサーバー/ジョブで同じ分に当たらないようにしてる。他の利点は、ジョブのログが一箇所にまとめられること。cronの「出力テキストがあったらメールを送る」っていうのはただの面倒な挙動だし、どこかにリダイレクトしない限り、ジョブの出力を得る唯一の場所でもある。タイマーから始めるのと、systemctl start job.serviceをするのは同じだから、デバッグが簡単だし、実行時間の指定方法に関するいくつかの改善はかなり役立ってる。例えば、タイマーを「永続的」に設定すると、電源が切れたときに「失われた」実行は次回のブート後に実行されるから、「午前2時にバックアップを実行」というジョブがあって、その前に電源を切っても、朝一番にバックアップができる。バックアップのサンダリングハード問題を避けるために、ランダムな遅延や固定(マシンのUUIDによる)ランダム遅延もあるから、便利だよ。必要なら、ジョブのためにデバイスを起こすオプションもあるけど、シャットダウンの問題はユーザーに任されてる。次のタイマーのカウントを前のものから始めるか、ジョブの終了から始めるかを選ぶこともできる。あと、ジョブのサマリーページ(「このジョブはX回成功したけどY回失敗した」みたいな)もあったらいいなと思うけど、それは外部ツールに任せた方がいいかも。> crontabでPATHを設定できるよ。それが/etc/bashrc、~/.bashrc、~/.profile、~/.bash_profile、/etc/systemd/...などで設定されているよりも「予測」するのが難しいの?

systemdのタイマー大好き!少しずつansibleでデプロイしたcronジョブをタイマーに移行してる(今はansibleのコピーだけ!)。journalctlとの統合、特にsyslogがなくなったDebian 13みたいな新しいOSでは本当にいい感じ。デバッグのためにサービスを手動で起動できるのもすごく便利。動かないcronジョブはコピー&ペーストや余分なシェルスクリプトを書くのが面倒だったからね。cronジョブのstdoutのブラックホールについてはもう触れたくもない。systemdサービスを監視するのは今まで通りできるし、失敗したときに通知ももらえるし。オープンソースプロジェクトがタイマーをデプロイ方法として推奨するのをどんどん見かけるようになって、いいことだと思う!

ますます多くのオープンソースプロジェクトがタイマーを推奨してる タイマーを推奨するプロジェクトには全然問題ないよ。無視してcronを使えるならね。

主要なディストリビューションの一つ(redhatかdebian、どっちだったか忘れたけど)がsystemd-cronを使ってると思う。cronはsystemdの薄いラッパーに過ぎないんだ。ユニットファイルを直接書くことでより強力になるけど、シンプルなcronジョブだけが必要なら、昔のインターフェースもまだ使えるよ。

うん、家のサーバーで@rebootジョブといくつかの定期ジョブにこれを使ってるよ。ユーザークロンタブを使ってるから、「未知のシェル/PATH/etc.」を回避するために、毎ジョブの前に/some/shell -l myjob.shとか、. ~/.profile && cd /some/where && ./job >>cron.log 2>&1って書いてる。

私たちは何十年もcronを問題なく使ってきたし、その明確な限界の中でうまく機能してた。でも今は明らかに盲目だったし、間違ってた。唯一の真の解決策はもちろんsystemdだね。

レナートに感謝。お前らのような堕落した異端者たちがついに彼の栄光の創造物の光を見始めたんだな。お前のsystemd-journaldが崇められますように。

実際にうまくいってるの?私は全然うまくいってないんだけど。systemdのファンではないけど、cronの悪い経験が多すぎて、今ではsystemdタイマーを選ぶようになった。意味不明な問題で動かないcronをトラブルシュートするのに何時間も無駄にしたり、成功を監視するために汚いハックを使ったりしてた。数年前、すごくシンプルなbashスクリプトをcronで実行しようとしたら、理由もなく途中で止まっちゃった。ログには何も出てこないし、直接実行したら問題なかったのに、cronだとループの途中で止まった。原因は結局わからず、諦めてタイマーを使ったらうまくいった。それ以来、cronには触ってない。監視やトラブルシューティングの簡単さだけでも、切り替える価値があるよ。

自分が快適に使えるものを使うし、他の人もそうすべきだと思う。CronD、SystemD、atD、シェルスクリプトの複数の条件チェック、何でも好きなものを使えばいい。間違った答えなんてないし、やったことを文書化してコメントを追加すればいい。cronにはコメントも許可されてるし。もし誰かが複雑でわけのわからない時間構造をcronに入れ続けるなら、その呪文を解読させるべきだし、シンプルにするまでしつこく言ってやればいい。cronエントリにコメントを残すか、彼らとそのマネージャーが辞めるまでね。ちなみに、変なcronの時間/日付の呪文を解読できるウェブアプリが出てくることが多いよ。[1] これには右上にgitリポジトリがあるけど、私のリポジトリじゃない。彼らのサイトがいつか消えたときのために、クローンしておくといいかも。[1] - https://crontab.cronhub.io/

これはまずいコメントかもしれないけど、cronの方が好きかも!特定の仕事のために設計されたツールだし…。

ヘッディングに何があったのか気になる。前は大丈夫だったのに、今はめちゃくちゃになってる。