目次にジャンプページナビゲーションにジャンプ: 前のページ[アクセスキーp]/次のページ[アクセスキーn]
documentation.suse.com / systemdタイマの操作

systemdタイマの操作

発行日: 12/11/2024
概要

定期的なバックアップスクリプトの実行から、コンピュータの起動後直ちに特定のプロセスを開始する処理まで、Linuxシステム上でスケジュール設定を必要とする多数のタスクがあります。systemdタイマは、ジョブやサービスをスケジュール設定し、管理するための柔軟なメカニズムを提供します。

目的

この記事は、タイマの作成、保守、テスト、トラブルシューティング、およびcronからの移行を網羅したsystemdタイマの全容の概要を提供することを目的としています。

所要時間

systemdタイマの例を作成するには10分を要します。また、systemdタイマの仕組みを十分に理解するには最長で30分が必要です。

要件

1 systemdタイマのコンセプト

systemdタイマユニットは、Linux上でジョブのスケジュールを設定する機能を提供します。これらのジョブの実行時間は、日時またはイベントに基づいて設定できます。

systemdタイマユニットは、ファイル名拡張子.timerで識別できます。各タイマファイルには、その制御対象になるサービスファイルが必要です。つまり、タイマファイルは、対応するサービスファイルを有効にし、管理します。systemdタイマは次の機能をサポートしています。

  • タイマユニットを使用してスケジュールするジョブを、他のsystemdサービスに依存して動作するものとすることができます。タイマユニットは通常のsystemdサービスとして扱われるので、systemctlで管理できます。

  • タイマは、カレンダイベントでトリガされるリアルタイムタイマまたは特定の開始点から指定された時間が経過するとトリガされる単調タイマとすることができます。

  • タイマユニットはシステムジャーナルに記録されるため、監視やトラブルシューティングが容易になります。

  • タイマでは、中央管理サービスであるsystemdを使用します。

  • 予定のタイマ実行時間でシステムがオフになっている場合は、システムが再度稼働したときにタイマが実行されます。

2 タイマの作成

次の例では、ブート時間後にhelloworld.shシェルスクリプトをトリガし、有効化された時刻を基準にして24時間ごとに実行を繰り返すタイマを設定する方法を示しています。また、このトリガを月曜日から金曜日の毎日午前10時にも実行します。

2.1 Hello Worldの例

  1. 次の内容で/etc/systemd/system/helloworld.serviceファイルを作成します。

    [Unit]
    Description="Hello World script"
    
    [Service]
    ExecStart=/usr/local/bin/helloworld.sh

    これは、どのアプリケーションを実行するかをsystemdに指示するsystemdサービスファイルです。

  2. 次の内容で/etc/systemd/system/helloworld.timerファイルを作成します。

    [Unit]
    Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"
    
    [Timer]
    OnBootSec=5min
    OnUnitActiveSec=24h
    OnCalendar=Mon..Fri *-*-* 10:00:*
    Unit=helloworld.service
    
    [Install]
    WantedBy=multi-user.target

    これは、各サービスファイルのアクティベーションを制御するタイマファイルです。

  3. 前記で作成したファイルにエラーがないことを確認します。

    > systemd-analyze verify /etc/systemd/system/helloworld.*

    このコマンドから出力が返されなければ、ファイルは検証に適合しています。

  4. タイマを起動します。

    > sudo systemctl start helloworld.timer

    現在のセッションでのみタイマを有効にします。

  5. タイマを有効にして、ブート時にタイマが有効になることを確認します。

    > sudo systemctl enable helloworld.timer

2.2 説明に沿った例

例 1: サービスファイル
[Unit]
Description="Hello World script"1

[Service]
ExecStart=/usr/local/bin/helloworld.sh2

1

サービスファイルの目的の簡単な説明。

2

実行するアプリケーション。

[Unit]セクションと[Service]セクションは、サービスファイルが機能するために最小限必要なセクションです。通常、systemdサービスファイルには、サービスでロードする1つ以上のターゲットを指定した[Install]セクションがあります。この情報はタイマファイルから提供されるので、タイマのサービスファイルにこのセクションは不要です。高度な設定についてはManaging systemd targets with systemctlを参照してください。

例 2: タイマファイル
[Unit]
Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"1

[Timer]
OnBootSec=5min2
OnUnitActiveSec=24h3
OnCalendar=Mon..Fri *-*-* 10:00:*4
Unit=helloworld.service5

[Install]
WantedBy=multi-user.target6

1

タイマファイルの簡単な説明。

2

システムブートの5分後にサービスをトリガするタイマを指定します。詳細については単調タイマを参照してください。

3

サービスを有効にした時点から24時間後にサービスをトリガするタイマを指定します(つまり、このタイマは1日に1回サービスをトリガします)。詳細についてはリアルタイムタイマを参照してください。

4

決まった時点(この例では、月曜日から金曜日の毎日午前10時)にサービスをトリガするタイマを指定します。詳細についてはリアルタイムタイマを参照してください。

5

実行するサービスファイル。

6

タイマが動作するsystemdターゲット。systemdターゲットの詳細については、Managing systemd targets with systemctlを参照してください。

3 タイマの管理

systemctlコマンドを使用してタイマを管理できます。

タイマの起動と停止
> sudo systemctl start TIMER.timer
> sudo systemctl restart TIMER.timer
> sudo systemctl stop TIMER.timer
タイマの有効化と無効化
> sudo systemctl enable TIMER.timer
> sudo systemctl disable TIMER.timer
タイマファイルの内容の表示
> sudo systemctl cat TIMER.timer
特定のタイマの確認
> sudo systemctl status TIMER.timer
例 3: タイマのステータス
> sudo systemctl status helloworld.timer
● helloworld.timer - "Run helloworld.service 5min after boot and every 24 hours
relative to activation time"1
Loaded: loaded (/etc/systemd/system/helloworld.timer; disabled; vendor preset: disabled)2
Active: active (waiting) since Tue 2022-10-26 18:35:41 CEST; 6s ago3
Trigger: Wed 2022-10-27 18:35:41 CEST; 23h left4
Triggers: ● helloworld.service5
6
Oct 26 18:35:41 neo systemd[1]: Started "Run helloworld.service 5min after boot and every 24 hours relative to activation time".7

1

タイマのファイル名と説明。

2

タイマが正常に解析されてメモリ内に保持(ロード)されているかどうかを一覧にします。また、タイマファイルのフルパスを示し、タイマがブート時に開始されるか(有効)、されないか(無効)を示します。最初の値は現在のシステム設定を示し、2番目の値はベンダによるプリセット値を示しています。

3

タイマがアクティブ(イベントのトリガを待機している状態)か非アクティブかを示します。アクティブな場合、前回のアクティベーションからの経過時間も表示されます(この例では6秒)。

4

タイマが次回トリガされる日時。

5

タイマによってトリガされるサービスファイルの名前。

6

マニュアルページなどのドキュメントを示すオプション行。そのような情報がない場合は、この例のように空の行になります。

7

タイマによって作成された最新のジャーナルエントリ。

システムで利用できるすべてのタイマを一覧表示するにはsystemctl list-timersを使用します。次のオプションを指定できます。

すべてのアクティブなタイマを一覧表示します。
> sudo systemctl list-timers
非アクティブなタイマも含め、すべてのタイマを一覧表示します。
> sudo systemctl list-timers --all
パターンに一致するすべてのタイマを一覧表示します。
> sudo systemctl list-timers PATTERN
> sudo systemctl list-timers --allPATTERN

PATTERNは、名前またはシェルのグロブ表現とする必要があります。オペレータ*?、および[]を使用できます。グロブパターンの詳細についてはman 7 globを参照してください。

特定の状態にあるタイマを一覧表示します。
> sudo systemctl list-timers --state=STATE

STATEに指定できる値は、activefailedloadsubです。詳細についてはman systemctlを参照してください。

例 4: タイマの一覧表示

どのsystemctl list-timersを実行しても次のようなテーブルが表示されます。この例では、パターンsnapper*に一致するすべてのアクティブなタイマが一覧表示されます。

> sudo systemctl list-timers snapper*
NEXT1                       LEFT2      LAST3                        PASSED4   UNIT5                  ACTIVATES6

-----------------------------------------------------------------------------------------------------------------------------
Tue 2022-10-26 19:00:00 CEST 39min left Tue 2022-10-26 18:00:29 CEST 19min ago snapper-timeline.timer snapper-timeline.service
Wed 2022-10-27 08:33:04 CEST 14h   left Tue 2022-10-26 08:33:04 CEST 9h ago    snapper-cleanup.timer  snapper-cleanup.service

1

タイマの次回実行日時。

2

タイマの次回実行までの残り時間。

3

タイマの前回実行日時。

4

タイマの前回実行からの経過時間。

5

タイマユニットの名前。

6

タイマで有効になるサービスの名前。

4 タイマのタイプ

systemdは、リアルタイム(カレンダに基づく)と単調(イベントに基づく)の2種類のタイマをサポートしています。一般的にタイマは永続的ですが、systemdを使用すると、現在のセッションでのみ有効な過渡タイマも設定できます。

リアルタイムタイマ

リアルタイムタイマは、カレンダイベントでトリガされます。その定義にはOnCalendarオプションを使用します。

日時に基づいてイベントをトリガするタイミングを指定できます。次のテンプレートを使用します。

OnCalendar=DayOfWeek1 Year-Month-Day2 Hour:Minute:Second3

1

曜日。指定できる値は、SunMonTueWedThuFriSatです。曜日を無視する場合は省略します。

2

日付。月と日を2桁で指定し、年を4桁で指定します。該当するあらゆる日時と一致するように、各値をワイルドカード*で置き換えることができます。

3

時刻。各値を2桁で指定します。該当するあらゆる日時と一致するように、各値をワイルドカード*で置き換えることができます。

これらのすべての値については、2つのドットを使用して連続する範囲を定義でき(Mon..Fri)、個々の値をコンマで区切って複数の値を列挙できます(Mon,Wed,Fri)。

例 5: リアルタイムタイマの例
  • 毎週金曜日の午後6時:

    OnCalendar=Fri *-*-* 18:00:00
  • 毎日午前5時:

    OnCalendar=Mon..Sun *-*-* 5:00:00
  • 日曜日と火曜日の午前1時と午前3時:

    OnCalendar=Tue,Sun *-*-* 01,03:00:00
  • 単一の日付:

    OnCalendar=Mo..Sun 2023-09-23 00:00:01
  • 時刻が異なる複数のトリガを指定するには、1つのタイマファイルに複数のOnCalendarエントリを作成します。

    OnCalendar=Mon..Fri *-*-* 10:00
    OnCalendar=Sat,Sun *-*-* 22:00

使用可能な機能とオプションの全リストについては、man 7 systemd.timeを参照してください。ここでは、次のトピックに関する追加情報が提供されています。

  • 構文の短縮と略語の使用

  • 繰り返しの指定

  • 月の特定の日を検索(月の最終日、最後の日曜日など)

  • タイムゾーンの適用

単調タイマ

単調タイマは、システムブートやシステムユニットのアクティベーションイベントなど、特定のイベントから指定の時間が経過するとトリガされます。この値は時間の単位(分、時間、日、月、年など)で定義します。使用できる単位は、usecmsecsecondsminuteshoursdaysweeksmonthsyearsです。単調タイマの定義で使用するオプションがいくつかあります。

  • OnActiveSec: ユニットのアクティベーションからの時間

    OnActiveSec=50minutes
  • OnBootSec: システムのブートからの時間

    OnBootSec=10hours
  • OnStartupSec: サービスマネージャの起動からの時間。システムサービスの場合、これはOnActiveSecにほぼ等しくなります。ユーザがログインするとサービスマネージャが起動するユーザサービスで、このオプションを使用します。

    OnStartupSec=5minutes 20seconds
  • OnUnitActiveSec: 該当サービスの前回有効化からの時間

    OnUnitActiveSec=10seconds
  • OnUnitInactiveSec: 該当サービスの前回無効化からの時間

    OnUnitInactiveSec=2hours 15minutes 18 seconds
過渡タイマ

過渡タイマは、現在のセッションでのみ有効な一時的タイマです。このタイマを使用すると、既存のサービスファイルを使用するか、プログラムを直接開始できます。systemd-runを実行することで過渡タイマを呼び出します。

次の例では、2時間ごとにhelloworld.serviceユニットを実行します。

> sudo systemd-run --on-active="2hours" --unit="helloworld.service"

コマンドを直接実行するには、次の構文を使用します。この例では、スクリプト/usr/local/bin/helloworld.shを直接呼び出します。

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh

コマンドがパラメータを取る場合は、スペースで区切って追加します。

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh --language=pt_BR

過渡タイマは、単調タイマまたはリアルタイムタイマとすることができます。次のスイッチがサポートされており、単調タイマで説明されているように動作します。

  • --on-active

  • --on-startup

  • --on-unit-active

  • --on-unit-inactive

  • --on-calendar

詳細については、man 1 systemd-runを参照してください。

5 カレンダエントリのテスト

systemdでは、リアルタイムタイマ用のカレンダタイマエントリをテストおよび作成するためのツール、systemd-analyze calendarが提供されています。このツールでは、リアルタイムタイマの設定に必要なOnCalendarエントリと同じ引数を使用できます。

スペースで区切って複数の引数を連結できます。テストする期間が正しい場合は、タイマが次回トリガされる日時(ローカル時間とUTC)が出力に表示されます。また、Normalized formの文字列も表示されます。タイマファイルではこの文字列を使用することを推奨します。次に例を示します。

> systemd-analyze calendar "Tue,Sun *-*-* 01,03:00:00"
Normalized form: Tue,Sun *-*-* 01,03:00:00
Next elapse: Sun 2021-10-31 01:00:00 CEST
(in UTC): Sat 2021-10-30 23:00:00 UTC
From now: 3 days left

> systemd-analyze calendar "Mon..Fri *-*-* 10:00" "Sat,Sun *-*-* 22:00"
Original form: Mon..Fri *-*-* 10:00
Normalized form: Mon..Fri *-*-* 10:00:00
Next elapse: Thu 2021-10-28 10:00:00 CEST
(in UTC): Thu 2021-10-28 08:00:00 UTC
From now: 19h left

Original form: Sat,Sun *-*-* 22:00
Normalized form: Sat,Sun *-*-* 22:00:00
Next elapse: Sat 2021-10-30 22:00:00 CEST
(in UTC): Sat 2021-10-30 20:00:00 UTC
From now: 3 days left

繰り返しタイマでは、–iterations Nスイッチを使用してトリガ時間を一覧表示し、想定どおりに動作するかどうかをテストします。引数Nには、テストの繰り返し回数を指定します。次の例の文字列は、日曜日の00:00:00から8時間ごとにトリガすることを指定します。

> systemd-analyze calendar --iterations 5 "Sun *-*-* 0/08:00:00"
Original form: Sun *-*-* 0/08:00:00
Normalized form: Sun *-*-* 00/8:00:00
Next elapse: Sun 2021-10-31 00:00:00 CEST
(in UTC): Sat 2021-10-30 22:00:00 UTC
From now: 3 days left
Iter. #2: Sun 2021-10-31 08:00:00 CET
(in UTC): Sun 2021-10-31 07:00:00 UTC
From now: 3 days left
Iter. #3: Sun 2021-10-31 16:00:00 CET
(in UTC): Sun 2021-10-31 15:00:00 UTC
From now: 4 days left
Iter. #4: Sun 2021-11-07 00:00:00 CET
(in UTC): Sat 2021-11-06 23:00:00 UTC
From now: 1 week 3 days left
Iter. #5: Sun 2021-11-07 08:00:00 CET
(in UTC): Sun 2021-11-07 07:00:00 UTC
From now: 1 week 3 days left

6 タイマの失敗を通知する電子メールの取得

systemdには、cronのMAILTOに相当する機能が用意されていません。次の手順は、タイマの失敗を通知する電子メールを有効にする方法について説明しています。

この手順は次の各ステップで構成されます。

  1. 電子メールを送信するスクリプトを作成します。

  2. この電子メール送信スクリプトを実行するsystemdサービスファイルを作成します。

  3. この電子メールサービスファイルをテストします。

  4. タイマで制御するサービスから、OnFailureを使用して、作成した電子メールサービスファイルを呼び出します。

次の例では、mailxパッケージのmailxコマンドを使用しています。Postfix電子メールサーバがインストールされ、正しく設定されている必要があります。

  1. スクリプト/usr/local/bin/send_systemd_emailを作成します。

    1. このスクリプトには、$1 (電子メールアドレス)と$2 (失敗通知が受信されたサービスファイルの名前)の2つのパラメータが必要です。これらのパラメータはいずれも、メールスクリプトを実行するユニットファイルで指定します。

      #!/bin/sh
      systemctl status --full "$2" | mailx -S sendwait\
       -s "Service failure for $2" -r root@$HOSTNAME $1
    2. スクリプトが実行可能であることを確認します。

      > sudo chmod 755 /usr/local/bin/send_systemd_email
  2. ファイル/etc/systemd/system/send_email_to_USER@.serviceを作成します。

    [Unit]
    Description=Send systemd status information by email for %i to USER
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/send_systemd_email EMAIL_ADDRESS %i
    User=root
    Group=systemd-journal

    ファイル内のUSEREMAIL_ADDRESSを、電子メールを受信するユーザのログイン名と電子メールアドレスに置き換えます。%iは、失敗したサービスの名前です(%nパラメータで電子メールサービスに渡されます)。

  3. サービスファイルを確認して、報告された問題を修正します。

    > systemd-analyze verify /etc/systemd/system/send_email_to_USER@.service

    このコマンドから出力が返されなければ、ファイルは検証に適合しています。

  4. 手順全体を確認するには、テスト用のdbusインスタンスを使用してサービスを開始します(現在実行している他のどのサービスも使用できます。あらゆるインストール環境でdbusサービスの動作が保証されているので、この例ではdbusを使用しています)。

    > sudo systemctl start send_email_to_USER@dbus.service

    サービスが正常に動作すれば、本文にdbusステータスメッセージが記述されて件名をService failure for dbusとした電子メールがEMAIL_ADDRESSに届きます(これはテストにすぎません。dbusサービスに問題は発生していないので、この電子メールを削除してもかまいません。どのようなアクションも不要です)。

    テストの電子メールが正常に送信されていれば、それをサービスファイルに取り込んで作業を続けます。

  5. サービスに電子メール通知を追加するには、失敗の通知対象とするサービスファイルのUnitセクションにOnFailureオプションを追加します。

    [Unit]
    Description="Hello World script"
    OnFailure1=send_email_to_USER2@%n3.service
    
    [Service]
    ExecStart=/usr/local/bin/helloworld.sh

    1

    OnFailureオプションは、引数としてサービス名を取ります。

    2

    サービスユニットファイル名をログイン名で置き換えます。

    3

    サービスの名前を指定します(この例ではhelloworld)。電子メールサービスファイルでは、この名前が%iで表現されます。

  6. これで、systemdサービスの失敗通知が正常に設定されました。

ヒント
ヒント: 複数のユーザへの電子メール通知の送信

電子メールサービスファイルでは、受信者の電子メールアドレスがハードコーディングされています。別のユーザに通知電子メールを送信するには、電子メールサービスファイルをコピーして、ファイル名のユーザログインとコピー内の電子メールアドレスを置き換えます。

複数の受信者に失敗通知を同時に送信するには、次のように、サービスファイルにそれぞれのサービスファイル名をスペースで区切って追加します。

OnFailure=send_email_to_tux@%n.service send_email_to_wilber@%n.service

7 通常のユーザとしてのタイマの使用

通常のユーザでもsystemdタイマを使用できます。バックアップ、イメージの処理、クラウドへのデータの移動など、繰り返し実行するタスクの自動化で効果的です。

システム規模タイマの場合と同じ手順とタスクが有効です。ただし、次のような違いがあります。

  • タイマとサービスファイルは~/.config/systemd/user/に配置する必要があります。

  • すべてのsystemctlコマンドとjournalctlコマンドは、--userスイッチを使用して実行する必要があります。systemd-analyzeでは、このオプションは不要です。

    通常のユーザは、次の例のようにユニットファイルへのパスを指定する必要があります。これを指定しない場合、同じ名前のシステム規模タイマが存在すると、それが代わりに実行されるか列挙されます。

    > systemctl --user start ~/.config/systemd/user/helloworld.timer
    > systemctl --user enable ~/.config/systemd/user/helloworld.timer
    > systemctl --user list-timers
    > journalctl --user -u helloworld.*
    > systemd-analyze verify ~/.config/systemd/user/helloworld.timer
重要
重要: ユーザタイマはアクティブなセッションでのみ実行可能

通常のユーザとして開始した他のsystemdサービスと同様に、ユーザタイマはユーザがログインしているときにのみ実行されます。代わりに、ブート時にユーザタイマを開始し、ログアウト後も実行し続けるには、影響を受ける各ユーザに対して「リンガ」を有効にします。

sudo loginctl enable-linger USER

詳細については、man 1 loginctlを参照してください。

重要
重要: 環境変数は非継承

systemdのユーザインスタンスでは、~/.profile~/.bashrcなどのスクリプトで設定した環境変数が継承されません。systemdの環境を確認するにはsystemctl --user show-environmentを実行します。

systemdの環境にない変数をインポートするには、~/.bashrcの末尾で次のコマンドを指定します。

systemctl --user import-environment VARIABLE1 VARIABLE2

8 cronからsystemdタイマへの移行

すべてのcronジョブをsystemdのタイマへ移行できます。手順と例はこちらをご覧ください。

  1. スクリプトを実行するサービスファイルを作成します。詳細については例1「サービスファイル」を参照してください。

  2. サービスファイルを実行するタイマファイルを作成します。一般的な手順については、例2「タイマファイル」を参照してください。

    1. カレンダのエントリを変換します。時間はcronとsystemdでは指定方法が異なります。次のパターンを変換テンプレートとして使用します。

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      変換したカレンダエントリをテストするには5項 「カレンダエントリのテスト」の手順に従います。

    2. 次のようにcronのニックネーム(@NICK)を変換します。

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. 変数の割り当てを変換します。systemdでの変数の割り当ては[Service]セクションに記述する必要があります。MAILTOは、この方法では変換できません。その変換方法については次のステップを参照してください。

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. 6項 「タイマの失敗を通知する電子メールの取得」の手順に従って、cronのMAILTO機能を置き換える電子メール通知を設定します。

例 6: cronからsystemdのタイマへの移行

以下は、ブートの5分後と、毎週月曜日~金曜日の10時にスクリプトhelloworld.shを呼び出すcrontabエントリです。

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

このスクリプトを呼び出すsystemdのサービスファイル(helloworld.service)は次のようになります。

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

タイマファイル(helloworld.timer)は次のようになります。

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:*
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

9 トラブルシューティングとFAQ

失敗したsystemdタイマをデバッグおよびトラブルシューティングする方法を説明します。systemdのタイマに関するFAQ (よくある質問と答え)の回答を参照してください。

9.1 エラーの回避

systemdのタイマでエラーを回避するには次のベストプラクティスに従います。

  • ExecStartを使用してサービスで指定した実行可能ファイルを正しく実行できることを確認します。

  • systemd-analyze verify FILEを実行して、サービスとタイマファイルの構文を確認します。

  • systemd-analyze calendar CALENDER_ENTRYを実行して、カレンダのエントリの実行時間を確認します。

9.2 イベントがトリガされない

systemdでは、重大ではないエラーがあるタイマを有効にすると、それらのエラーが暗黙的に無視されます。次に例を示します。

例 7: 致命的ではないエラーがあるsystemdタイマファイルの抜粋
[Timer]
OnBootSec=5min
OnClendar=Mon..Fri 10:00
Unit=helloworld.service

3行目に、OnCalendarではなくOnClendarを使用している構文エラーがあります。[Timer]セクションに2つ目のタイマエントリ(OnBoot)が含まれるため、このエラーは重大ではなく、無視されて何も表示されません。その結果、月曜日から金曜日までのトリガが実行されません。このエラーを検出するにはsystemd-analyze verifyコマンドを使用する以外にありません。

#  systemd-analyze verify /etc/systemd/system/helloworld.timer
/etc/systemd/system/helloworld.timer:7: Unknown key name 'OnClendar' in section 'Timer', ignoring.

9.3 システムジャーナルのエラー確認

すべてのsystemdサービスと同様に、タイマによってトリガされたイベントやアクションは、システムジャーナルに記録されます。トリガが想定どおりに動作しない場合は、journalctlを使用してログメッセージを確認します。ジャーナルをフィルタして関連する情報を表示するには、-uスイッチを使用してsystemdタイマとサービスファイルを指定します。このオプションを使用して、タイマおよび対応するサービスファイルのログエントリを表示します。

sudo journalctl -u  helloworld.timer -u helloworld.service

短縮形で十分な場合は次のとおりです。

sudo journalctl -u  helloworld.*

journalctlは、さまざまなオプションとフィルタをサポートするツールです。詳細については、man 1 journalctlを参照してください。次のオプションはタイマのトラブルシューティングで効果的です。

  • -b: 現在のブートのエントリのみを表示します。

  • -S today: 今日からのエントリのみを表示します。

  • -x: ログエントリの隣にヘルプテキストを表示します。

  • -f: 最新のエントリから開始し、新しいエントリが追加されるたびにログを継続的に出力します。短い間隔で発生するトリガの確認で有用です。CtrlCを押すと終了します。

9.4 systemdのタイマ: 実行されなかったトリガの再実行

systemdのタイマに想定したトリガ時刻にタイマが非アクティブであったかシステムがオフ状態であった場合、タイマを再度有効にすると、イベントに対して実行されなかったトリガを必要に応じて実行できます。この機能を有効にするには、次のように[Timer]セクションに設定オプションPersistent=trueを追加します。

[Timer]
OnCalendar=Mon..Fri 10:00
Persistent=true
Unit=helloworld.service

9.5 cronからsystemdのタイマへ移行する方法

すべてのcronジョブをsystemdのタイマへ移行できます。ここでは、cronジョブを移行するための一般的な手順を示します。

  1. スクリプトを実行するサービスファイルを作成します。詳細については例1「サービスファイル」を参照してください。

  2. サービスファイルを実行するタイマファイルを作成します。一般的な手順については、例2「タイマファイル」を参照してください。

    1. カレンダのエントリを変換します。時間はcronとsystemdでは指定方法が異なります。次のパターンを変換テンプレートとして使用します。

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      変換したカレンダエントリをテストするには5項 「カレンダエントリのテスト」の手順に従います。

    2. 次のようにcronのニックネーム(@NICK)を変換します。

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. 変数の割り当てを変換します。systemdでの変数の割り当ては[Service]セクションに記述する必要があります。MAILTOは、この方法では変換できません。その変換方法については次のステップを参照してください。

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. 6項 「タイマの失敗を通知する電子メールの取得」の手順に従って、cronのMAILTO機能を置き換える電子メール通知を設定します。

例 8: cronからsystemdのタイマへの移行

以下は、ブートの5分後と、毎週月曜日~金曜日の10時にスクリプトhelloworld.shを呼び出すcrontabエントリです。

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

このスクリプトを呼び出すsystemdのサービスファイル(helloworld.service)は次のようになります。

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

タイマファイル(helloworld.timer)は次のようになります。

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:*
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

10 詳細情報