技術ノート Linux cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

systemd がもたらした変更の 1 つは、cron よりも細かくジョブをスケジュールする新しい方法でした。一部の Linux ディストリビューションでは cron が同梱されなくなりました。 systemd タイマーをチェックしてみましょう。

systemd タイマーが cron を置き換える理由

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

cron の起源は 1975 年の Unix バージョン 7 にまで遡ります。その信頼性により、指定した日時に実行するタスクをスケジュールするツールとしてすぐに人気になりました。確かに、その構文はかなり風変わりです。頻繁に使用しない場合は、 ジョブをスケジュール するたびに詳細を調べる必要があるでしょう。

cron スケジュールでは、日と月に 1 から始まる番号が付けられます。ただし、曜日は日曜日から土曜日まで、0 から 6 までの番号が付けられます。また、システムによっては、7 が日曜日を意味する場合もあります。しかし、これは風変わりかもしれませんが、機能します。

systemd サービス マネージャーは、init ブート マネージャーの単純な置き換え以上のものをもたらしました。提供されたものの一部は、systemd タイマーの形式での cron の最新の代替品でした。これらは cron よりも高い柔軟性を提供し、別の外部ユーティリティを必要としません。これらはすべての systemd ディストリビューションに組み込まれています。

つまり、タイマーはすべての systemd インストールで同じように動作します。 cron および cron に似た代替品には多くのバージョンがあります。多数のコンピューター間で標準化する必要がある場合、systemd を使用すると作業が容易になります。同じタイマーはすべてのデバイスで同じように実行されます。実際、一部の systemd ベースのディストリビューションでは、標準製品の一部として cron が同梱されなくなりました。

当然のことですが、systemd は Red Hat の取り組みであるため、 Fedora を含む Red Hat 由来のディストリビューションには cron が同梱されていません。 Arch とその派生製品には cron が含まれていませんが、それはおそらく、適切なアプリケーションを追加するような最小限のディストリビューションを提供することと関係があるでしょう。 Solus などの他のディストリビューションでも、cron を含める必要はないと考えられます。もちろん、任意のディストリビューションに cron をインストールすることもできますが、そうするべきという説得力のある議論はありません。

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

systemd タイマーの仕組み

systemd タイマーを使用する場合は、2 つのファイルを作成する必要があります。 1 つは サービス ファイルです。サービスが実行されると、プロセスが起動されます。したがって、サービス ファイルはターゲット プロセスについて知っている必要があります。

作成する必要がある 2 番目のファイルは タイマー ファイルです。これにより、サービスがいつ開始されるかが決まります。したがって、タイマー ファイルはサービス ファイルについて知る必要があります。

タイマーは リアルタイム または 単調に することができます。リアルタイム タイマーはカレンダー イベントによってトリガーされます。単調タイマーは、起動などのシステム イベント後の一定期間でトリガーされます。ログ エントリはタイマー イベントのシステム ジャーナルに追加され、デバッグに役立ちます。

systemctl コマンドの status オプションを使用すると、コンピュータ上のタイマーを一覧表示できます。いくつかのシステム タイマーが自動的に作成されるため、タイマーを作成していない場合でも、このコマンドには出力が表示されます。

 systemctl status "*timer"

各説明には次の情報が含まれます。

  • タイマーの 名前 と説明 (指定されている場合)。
  • Loaded : ロード済みのステータスを表示します。通常、タイマーは読み取られてメモリにロードされます。タイマー ファイルへのディレクトリ パスが表示されます。タイマーが「有効」になっていることが期待されますが、オフにすることを選択した場合は、一時的に「無効」になる可能性があります。ベンダー プリセットは、タイマーが最初に作成されたときに「有効」に設定されたか「無効」に設定されたかを示します。
  • アクティブ : タイマーがアクティブになった日付と時刻を含む、アクティブなステータスを表示します。通常、タイマーは「アクティブ」としてリストされ、次回の起動日時まで「待機中」と表示されることが予想されます。
  • until : 紛らわしいことに、この行はタイマーには適用されません。それは無視して構いません。
  • Trigger : タイマーによって起動されるプロセスの名前が表示されます。
  • Triggers : 次にタイマーがトリガーされるタイミングと、プロセスが次に起動されるタイミングを示します。
  • ドキュメント : 一部のタイマーには関連ドキュメントがあります。この行はオプションであり、常に存在するとは限りません。

タイマーは実際には時間制御されるサービスなので、systemctl コマンドを使用して制御できます。

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

単純な systemd タイマーの作成

書かれた言葉は静的な媒体であるため、特定の時間にトリガーされるプロセスを示すのは困難です。これから行うことは、新しいタイマーによって起動されるスクリプトを作成し、タイムスタンプをログファイルに書き込むことです。これにより、サービスが機能していることと、最後にトリガーされたのがいつかがわかります。

date コマンド を使用してタイムスタンプを生成し、それをホーム ディレクトリの「timer.log」というファイルにリダイレクトします。

スクリプトは「/usr/local/bin/」ディレクトリに作成します。ここでは「gedit」エディターを使用していますが、お好みのエディターを使用できます。

 sudo gedit /usr/ local /bin/geek-timer.sh

これらの行をエディタにコピーし、ファイルを「geek-timer.sh」として保存し、エディタを閉じます。

 #!/bin/bash

echo "Timer fired: $(date) " >> /home/dave/timer.log

スクリプトを実行可能にする必要があります。

 sudo chmod +x /usr/ local /bin/geek-timer.sh

スクリプトが意図したとおりに動作することを確認してみましょう。

 geek-timer .sh
cat timer .log

これにより、スクリプトが期待どおりに実行され、タイムスタンプが「timer.log」ファイルに記録されることが検証されます。

次に、サービス ファイルを作成して、タイマーがトリガーされたときに起動するサービスを定義します。

 sudo gedit /etc/systemd/system/geek-timer.service

これらの行をエディタにコピーし、ファイルを「/etc/systemd/system/geek-timer.service」として保存し、エディタを閉じます。

 [Unit]
Description= "How-To Geek systemd timer"
Requires=geek-timer.timer

[Service]
Type=simple
ExecStart= /usr/ local/bin/geek-timer.sh
User=dave

「[Unit]」セクションには 2 行が含まれています。 「Description=」行は、サービスの目的を説明する単純な 1 行の行です。 「Requires=」行は、このサービスが「geek-timer.timer」タイマー ファイルに依存していることを示します。次にこのファイルを作成します。

「[サービス]」セクションにはもう少し詳しく説明されています。 「Type=」は「simple」で、これが基本的なサービスであることを意味します。他のオプションには、サービスが 1 回だけ実行されることを意味する「ワンショット」があります。

「ExecStart=」行は、サービスを開始する必要があるプロセスを示します。これは、以前に作成したスクリプトを指しています。

「User=」行は、どのユーザーがコマンドを実行するかを定義します。これがないと、プロセスは root によって起動されます。

次に、タイマー ファイルを作成します。これは、サービスがいつ起動されるかを定義します。サーバー ファイルとタイマー ファイルには同じベース名を使用し、異なる拡張子を付けることをお勧めします。

 sudo gedit /etc/systemd/system/geek-timer.timer

これらの行をエディタにコピーし、ファイルを「/etc/systemd/system/geek-timer.timer」として保存し、エディタを閉じます。

 [Unit]
Description= "Timer for the geek-timer.service"

[Timer]
Unit=geek-timer.service
OnBootSec=5min
OnUnitActiveSec=1min

[Install]
WantedBy=timers.target

「[Unit]」セクションには「Description=」というテキスト行が含まれています。 「[タイマー]」セクションには 3 つの設定があります。 「Unit=」行は、このタイマーがトリガーされたときにどのサービスを起動する必要があるかを示します。 「OnBootSec=」行は、コンピュータの起動から 5 分後にサービスを起動するようにシステムに指示します。 「OnUnitActiveSec=」行は、サービスが最後にアクティブ化されてから 1 分後にサービスを起動するようにタイマーに指示します。

つまり、コンピューターが起動してから 5 分後にサービスが起動します。その後、サービスは 1 分間隔で繰り返されます。

「[Install]」セクションには、「timers.target」を指定する「WantedBy=」行が含まれています。 「timers.target」は、起動後にアクティブになるすべてのタイマー ユニットを設定する特別なターゲット ユニットで、すべての基本的な systemd タイマーに適しています。

systemctl status コマンドを使用して、新しいタイマーを確認できます。

 systemctl status geek-timer .service

エラーは報告されておらず、これは問題ありません。サービスを開始していないため、非アクティブです。ここで再起動しても、サービスとタイマーは有効になりません。タイマーを開始して有効にしましょう。

 sudo systemctl enable geek-timer .timer
sudo systemctl start geek-timer .timer

テスト コンピュータを再起動して、起動後の 5 分間の猶予期間が守られているかどうかを確認し、ステータスをもう一度確認しました。

 systemctl status geek-timer .service

これは、PC が 12:18 に起動し、タイマーが 12:23 にトリガーされることを示しています。要求した 5 分後の起動オプションは正しく処理されています。 5 分間が経過するのを待ってから、すぐに同じコマンドを実行しました。

 systemctl status geek-timer .service

トリガー時間が 12:23 から 12:24 に 1 分移動していることがわかります。これは、タイマーが「1 分ごとに繰り返すフェーズ」に入ったことを意味します。

数分後にログファイルを確認すると、最初のトリガー時間が 12:23 で、その後の起動は 1 分間隔で発生していることがわかります。

猫タイマー.ログ

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

タイミングの微調整

繰り返しイベントのトリガー時間は少しあいまいです。ログファイル内のイベントの間隔が 1 分であると述べたのはこのためです。正確に同時にトリガーするようにスケジュールされたタイマーが実際には時間差でトリガーされるようにするために、トリガー時間に小さなランダム要素が追加されています。通常、バックアップの開始やその他のシステム ハウスキーピング アクティビティなどのタスクの場合は、これで十分な精度です。

より厳密な解像度が必要な場合は、マイクロ秒のタイミングを使用できます。この行をタイマー ファイルの「[Timer]」セクションに追加すると、システムが 1 マイクロ秒の分解能を使用するように設定されます。

 AccuracySec=1us

これらは、使用できる精度設定とその参照方法です。

  • マイクロ秒 : us、μs msec、ms
  • : 秒、秒、秒、秒
  • : 分、分、分、分
  • 時間 : 時、時、時、時
  • 日数 : 日、日、日
  • : 週、週、w
  • : 月、月、M
  • : 年、年、y

特定の日時にタイマーをトリガーするには、「OnCalendar」設定を使用します。これは、タイマー ファイルの「[Timer]」セクションに記述されます。一般的な形式は次のとおりです。

 OnCalendar=DayOfTheWeek YYYY-MM-DD HH:MM:SS

DayOfTheWeek はオプションです。他の値は、毎分や毎時間などの「毎」を意味するアスタリスク「*」に置き換えます。日と月には名前または数値を使用し、値の選択を表すにはカンマ区切りのリストを使用できます。値の範囲は、範囲の開始と値を区切る 2 つのピリオド「..」を使用して示されます。

これにより、タイマーが毎月第 1 金曜日の 01:15 にトリガーされるように設定されます。

 OnCalendar=Fri *-*-1..7 01:15:00

これにより、毎日 19:00 にプロセスが実行されます。

 OnCalendar=*-*-* 19:00:00

タイマーには複数のトリガー時間を設定できます。これにより、営業日と週末では異なる時間にプロセスが実行されます。

 OnCalendar=Mon..Fri 23:00:00
OnCalendar=Sat,Sun 19:00:00

systemd time のマニュアル ページには、 時間形式と多くの役立つヒントとコツが完全に説明されています。

cron ジョブを systemd タイマーに置き換える方法 (およびその理由)

優れた柔軟性と使いやすさ

systemd タイマーの柔軟性の多くは、奇抜なカレンダー イベントに対応できる方法にあります。たとえば、金曜日を除くすべての日の 15:00 にトリガーされるようにタイマーを設定するには、次の形式を使用できます。

 Mon . .Thu , Sat , Sun * - * - * 15 :00 :00

カンマ区切りのリストと範囲を組み合わせることで、あらゆる種類の複雑な要件に対応するリアルタイム トリガーを簡単に作成できます。

プロセスを起動するサービスと、サービスの起動を管理するタイマー ファイルを作成するという概念を理解できれば、systemd タイマーを理解するまでの 90% は完了したことになります。最後の 10% は、カレンダーイベントの優雅な力を受け入れています。

「 cron ジョブを systemd タイマーに置き換える方法 (およびその理由)」に関するベスト動画選定!

【A試験_ハードウェア】06. メモリの分類 | 基本情報技術者試験
LPIC 1 – 59 – 107.2 – Automate admin tasks by scheduling them (cron, crontab, at & systemd timers)