「Systemd/タイマー」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) 細 (→サービス) |
Kusanaginoturugi (トーク | 投稿記録) (校正(でき・出来)) |
||
(5人の利用者による、間の13版が非表示) | |||
1行目: | 1行目: | ||
{{Lowercase title}} |
{{Lowercase title}} |
||
− | [[Category: |
+ | [[Category:システム管理]] |
+ | [[de:Systemd/Timers]] |
||
− | [[Category:ブートプロセス]] |
||
[[en:Systemd/Timers]] |
[[en:Systemd/Timers]] |
||
+ | [[es:Systemd/Timers]] |
||
[[fr:Systemd/cron]] |
[[fr:Systemd/cron]] |
||
− | [[ |
+ | [[pt:Systemd/Timers]] |
+ | [[ru:Systemd (Русский)/Timers]] |
||
+ | [[zh-hans:Systemd/Timers]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
{{Related|systemd}} |
{{Related|systemd}} |
||
15行目: | 18行目: | ||
== タイマーユニット == |
== タイマーユニット == |
||
− | タイマーは拡張子が {{ic|.timer}} の ''systemd'' のユニットファイルです。他の[[systemd# |
+ | タイマーは拡張子が {{ic|.timer}} の ''systemd'' のユニットファイルです。他の [[systemd#ユニットファイル|ユニット設定ファイル]] と似ていますが特別に {{ic|[Timer]}} セクションが存在します。{{ic|[Timer]}} セクションにはタイマーが作動する時間と処理を定義します。タイマーには2つのタイプがあり、どちらか一つを使って定義されます: |
− | * '''モノトニックタイマー'''は刻々と変わる開始点と相応したタイムスパンの後に作動します。様々なモノトニックタイマーが存在しますがどれも次のような形式です: {{ic|1=On''Type''Sec=}} |
+ | * '''モノトニックタイマー''' は刻々と変わる開始点と相応したタイムスパンの後に作動します。様々なモノトニックタイマーが存在しますがどれも次のような形式です: {{ic|1=On''Type''Sec=}} {{ic|OnBootSec}} と {{ic|OnActiveSec}} は全てのモノトニックタイマーで共通です。 |
* '''リアルタイムタイマー''' (別名ウォールクロックタイマー) は (cron のジョブと同じように) カレンダーイベントにあわせて作動します。{{ic|1=OnCalendar=}} オプションを使って定義を行います。 |
* '''リアルタイムタイマー''' (別名ウォールクロックタイマー) は (cron のジョブと同じように) カレンダーイベントにあわせて作動します。{{ic|1=OnCalendar=}} オプションを使って定義を行います。 |
||
− | タイマーのオプションについては {{ |
+ | タイマーのオプションについては {{man|5|systemd.timer}} の [[man ページ]] で説明されています。カレンダーイベントやタイムスパンの引数構文については {{man|7|systemd.time}} の [[man ページ]] で説明されています。 |
+ | |||
+ | {{Note|''systemd'' は、ブート後にアクティブにする必要があるすべてのタイマーを設定するターゲット {{ic|timers.target}} を提供します (詳細については、{{man|7|systemd.special}} を参照してください) これを使用するには、タイマーの {{ic|[Install]}} セクションに {{ic|1=WantedBy=timers.target}} を追加し、タイマーユニットを [[有効化]] します。}} |
||
== サービスユニット == |
== サービスユニット == |
||
39行目: | 44行目: | ||
* (有効でないタイマーも含めて) 全てのタイマーを確認したい場合、{{ic|systemctl list-timers --all}} を使って下さい。 |
* (有効でないタイマーも含めて) 全てのタイマーを確認したい場合、{{ic|systemctl list-timers --all}} を使って下さい。 |
||
* タイマーによって実行するサービスの状態は、今現在作動しているのでない限り、inactive になります。 |
* タイマーによって実行するサービスの状態は、今現在作動しているのでない限り、inactive になります。 |
||
− | * タイマーがズレる場合は、{{ic|/var/lib/systemd/timers}} にある {{ic|stamp-*}} ファイルを削除してみてください。stamp ファイルはタイマーが実行された最後の時刻を記録しており、ファイルを削除することでタイマーの次の作動時に systemd が再構成を行います。 |
+ | * タイマーがズレる場合は、{{ic|/var/lib/systemd/timers}} もしくは {{ic|~/.local/share/systemd/}} にある {{ic|stamp-*}} ファイルを削除してみてください。stamp ファイルはタイマーが実行された最後の時刻を記録しており、ファイルを削除することでタイマーの次の作動時に systemd が再構成を行います。 |
}} |
}} |
||
64行目: | 69行目: | ||
=== リアルタイムタイマー === |
=== リアルタイムタイマー === |
||
− | 一週間ごとに起動するタイマー (月曜日の午前12:00に実行)。システムの電源が切られていたなどの理由で、最後の起動時間を過ぎていた場合、すぐに実行されます ({{ic |
+ | 一週間ごとに起動するタイマー (月曜日の午前12:00に実行)。システムの電源が切られていたなどの理由で、最後の起動時間を過ぎていた場合、すぐに実行されます ({{ic|1=Persistent=true}} オプション): |
{{hc|/etc/systemd/system/foo.timer|<nowiki> |
{{hc|/etc/systemd/system/foo.timer|<nowiki> |
||
77行目: | 82行目: | ||
WantedBy=timers.target</nowiki>}} |
WantedBy=timers.target</nowiki>}} |
||
+ | もっと細かく日時を指定する必要がある場合、次の形式で {{ic|OnCalendar}} イベントを制御できます: {{ic|DayOfWeek Year-Month-Day Hour:Minute:Second}}。アスタリスクをワイルドカードとして使うことができ、カンマで複数の日時を指定することができます。値を {{ic|..}} で区切ることで連続的に日程を指定することも可能です。 |
||
− | {{Tip|{{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。{{ic|1=OnCalendar=Wed, 23:15}} のような特定のイベントで起動するタイマーを使うときはよく考えてからにしてください。[[#注意事項]]を参照。}} |
||
+ | 例えば、以下の場合、毎月の1日から4日まで、月曜日か火曜日の場合にのみ、午後0時にサービスを実行します: |
||
− | === サービス === |
||
− | {{hc|/etc/systemd/system/foo.service|<nowiki> |
||
− | [Unit] |
||
− | Description=daily foo |
||
− | RefuseManualStart=no |
||
− | RefuseManualStop=yes |
||
+ | OnCalendar=Mon,Tue *-*-01..04 12:00:00 |
||
− | [Service] |
||
+ | |||
− | Type=oneshot |
||
+ | 毎月第1土曜日にサービスを実行したい場合は以下のようになります: |
||
− | ExecStart=/home/<user>/scripts/foo.sh |
||
+ | |||
− | </nowiki>}} |
||
+ | OnCalendar=Sat *-*-1..7 18:00:00 |
||
+ | |||
+ | 毎朝4時に実行したい場合は以下のようになります: |
||
+ | |||
+ | OnCalendar=*-*-* 4:00:00 |
||
+ | |||
+ | {{ic|OnCalendar}} は複数指定でき、複数の異なるタイミングでサービスを実行できます。次の例では、平日の22:30および土日の20:00に実行されます: |
||
+ | |||
+ | OnCalendar=Mon..Fri 22:30 |
||
+ | OnCalendar=Sat,Sun 20:00 |
||
+ | |||
+ | ディレクティブの最後にタイムゾーンを指定することもできます (受け入れられる値をリストするには、{{ic|timedatectl list-timezones}} を使用します。) |
||
+ | |||
+ | OnCalendar=*-*-* 02:00:00 Europe/Paris |
||
+ | |||
+ | 詳しくは {{man|7|systemd.time}} を見てください。 |
||
+ | |||
+ | {{Tip| |
||
+ | * {{ic|OnCalendar}} の日時の指定方法は ''systemd-analyze'' ユーティリティの {{ic|calendar}} オプションを使用することでテストすることができます。タイマーユニットで使用したときに次に実行される日時も確認できます。例えば、{{ic|systemd-analyze calendar weekly}} や {{ic|systemd-analyze calendar "Mon,Tue *-*-01..04 12:00:00"}} のようにコマンドを実行することでテストできます。 |
||
+ | * {{Pkg|libfaketime}} でインストールできる {{ic|faketime}} コマンドを使うと、これらのコマンドを使ったいろいろなシナリオをテストするのに便利です。 |
||
+ | * {{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。このような問題は {{ic|RandomizedDelaySec}} オプションを使用してタイマーの起動時間を散らすことで解決できます。{{man|5|systemd.timer}} を参照してください。 |
||
+ | * {{ic|AccuracySec}} のデフォルト値 ''1m'' の不正確さを避けるために、オプション {{ic|1=AccuracySec=1us}} を [Timer] セクションに追加します。{{man|5|systemd.timer}} も参照してください。 |
||
+ | * 一部のオプション ({{ic|WakeSystem}}) は、特定のシステム機能を必要とし、タイマーの開始を妨げる場合があり、その結果、次のエラーメッセージが表示されます: "Failed to enter waiting state: Operation not supported" そして "Failed with result 'resources'." |
||
+ | }} |
||
+ | |||
+ | == 一時的な .timer ユニット == |
||
+ | |||
+ | {{ic|systemd-run}} を使うことで一時的な {{ic|.timer}} ユニットを作ることができます。サービスファイルを作成しなくても、特定時刻にコマンドが実行されるように設定することが可能です。例えば、以下のコマンドは30秒後にファイルを作成します: |
||
+ | |||
+ | # systemd-run --on-active=30 /bin/touch /tmp/foo |
||
+ | |||
+ | タイマーファイルが存在しない既存のサービスファイルを指定することもできます。例えば、以下のコマンドは12.5時間後に {{ic|''someunit''.service}} という名前の systemd ユニットを起動します: |
||
+ | |||
+ | # systemd-run --on-active="12h 30m" --unit ''someunit''.service |
||
+ | |||
+ | 詳しくは {{man|1|systemd-run}} を見てください。 |
||
== cron を置き換える == |
== cron を置き換える == |
||
100行目: | 136行目: | ||
* タイマーとは別個にジョブを実行することが簡単にできます。これによってデバッグが楽になります。 |
* タイマーとは別個にジョブを実行することが簡単にできます。これによってデバッグが楽になります。 |
||
− | * 特定の環境で動作するようにジョブを設定することができます ({{ |
+ | * 特定の環境で動作するようにジョブを設定することができます ({{man|5|systemd.exec}} [[man ページ]]を参照)。 |
* ジョブを [[cgroups]] の支配下に置けます。 |
* ジョブを [[cgroups]] の支配下に置けます。 |
||
* 他の ''systemd'' ユニットに依存するようにジョブを設定できます。 |
* 他の ''systemd'' ユニットに依存するようにジョブを設定できます。 |
||
111行目: | 147行目: | ||
* 冗長性: ''systemd'' を使って定期的なジョブを設定するには2つのファイルを作成して2回 {{ic|systemctl}} コマンドを実行します。それに対して crontab には一行を追加するだけです。 |
* 冗長性: ''systemd'' を使って定期的なジョブを設定するには2つのファイルを作成して2回 {{ic|systemctl}} コマンドを実行します。それに対して crontab には一行を追加するだけです。 |
||
* メール: ジョブが失敗した時にメールを送信する cron の {{ic|MAILTO}} と同等なものは存在しません。ただし各サービスに {{ic|1=OnFailure=}} オプションを使うことで同じような機能を設定することはできます。 |
* メール: ジョブが失敗した時にメールを送信する cron の {{ic|MAILTO}} と同等なものは存在しません。ただし各サービスに {{ic|1=OnFailure=}} オプションを使うことで同じような機能を設定することはできます。 |
||
− | * ランダム遅延: インターバルを指定してタイマーの実行をランダムに分散する cron の {{ic|RANDOM_DELAY}} と同じ機能はありません ([https://bugs.freedesktop.org/show_bug.cgi?id=82084 バグレポート]や[https://wiki.archlinux.org/index.php?title=Talk:Systemd/Timers&oldid=356408#Parallelization_section_is_confusing テスト結果]を参照)。同時に実行して欲しくないサービスには、手動でオーバーラップを少なくするようにタイマーを設定する必要があります。 |
||
− | |||
− | :{{note|タイマーを自動的にずらすには {{ic|AccuracySec}} オプションが役に立つかもしれません。ただし"全てのローカルなタイマーユニット間で同期が行われる"ので注意してください ({{ic|systemd.timer(5)}})。言い換えれば、{{ic|AccuracySec}} は全てのタイマーの作動時間を同じ分だけずらします。例えば、{{ic|1=AccuracySec=15m}} を使っている {{ic|1=OnCalendar=daily}} のタイマーユニットは全て、00:00 から 00:15 の間の同一時刻に関連するサービスを起動します。}} |
||
=== MAILTO === |
=== MAILTO === |
||
− | Cron の {{ic|MAILTO}} のように、systemd で、ユニットが失敗したときにメールを送信するように設定できます。それにはまず2つのファイルが必要です: メールを送信するための実行可能ファイルと、実行可能ファイルを起動するための ''.service''。以下の例では、{{ic|sendmail}} を使用するシェルスクリプトが実行可能ファイルになっています: |
+ | Cron の {{ic|MAILTO}} のように、systemd で、ユニットが失敗したときにメールを送信するように設定できます。それにはまず2つのファイルが必要です: メールを送信するための実行可能ファイルと、実行可能ファイルを起動するための ''.service''。以下の例では、{{ic|sendmail}} ({{ic|smtp-forwarder}} を含むパッケージにはすべて含まれています) を使用するシェルスクリプトが実行可能ファイルになっています: |
{{hc|/usr/local/bin/systemd-email|<nowiki>#!/bin/bash |
{{hc|/usr/local/bin/systemd-email|<nowiki>#!/bin/bash |
||
133行目: | 166行目: | ||
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の ''.service'' はそれらの引数を渡します: |
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の ''.service'' はそれらの引数を渡します: |
||
− | {{hc|/etc/systemd/system/status-email- |
+ | {{hc|/etc/systemd/system/status-email-''user''@.service|2=[Unit] |
− | Description=status email for % |
+ | Description=status email for %i to ''user'' |
[Service] |
[Service] |
||
Type=oneshot |
Type=oneshot |
||
− | ExecStart=/usr/local/bin/systemd-email |
+ | ExecStart=/usr/local/bin/systemd-email ''address'' %i |
User=nobody |
User=nobody |
||
− | Group=systemd-journal |
+ | Group=systemd-journal}} |
− | </nowiki>}} |
||
− | メールを送信するユ |
+ | {{ic|''user''}} はメールを送信するユーザーに、{{ic|''address''}} はユーザーのメールアドレスに置き換えてください。受信者はハードコードされますが、インスタンスパラメータとしてユニットファイルを渡すことで、上記のサービスだけで他のユニットのメールも送ることができます。{{ic|status-email-''user''@dbus.service}} を[[systemd#ユニットを使う|起動]]して、メールが受け取れることを確認してください。 |
+ | 問題ないようでしたら、メールを送って欲しいユニットの {{ic|[Unit]}} セクションに {{ic|1=OnFailure=status-email-''user''@%n.service}} を追加してください。{{ic|%n}} はユニットの名前をテンプレートに指定します。 |
||
− | {{bc|# systemctl start status-email-user1@dbus.service}} |
||
+ | {{note| |
||
− | 問題ないようでしたら、メールを送って欲しいユニットの {{ic|[Unit]}} セクションに {{ic|1=OnFailure=status-email-user1@%n.service}} を追加してください。{{ic|%n}} はユニットの名前をテンプレートに指定します。 |
||
+ | *[[SSMTP#セキュリティ]] にしたがって SSMTP を設定した場合、ユーザー {{ic|nobody}} は {{ic|/etc/ssmtp/ssmtp.conf}} にアクセスすることができず、{{ic|systemctl start status-email-''user''@dbus.service}} コマンドは失敗します。{{ic|status-email-''user''@.service}} モジュールの User に {{ic|root}} を使うことでこれを回避できます。 |
||
− | |||
+ | * メールスクリプトで {{ic|mail -s somelogs ''address''}} を使用すると、{{ic|mail}} はフォークして、systemd はスクリプトの終了を確認したときに mail プロセスを終了します。{{ic|mail -Ssendwait -s somelogs ''address''}} として mail がフォークしないようにしてください。}} |
||
− | {{note|[[SSMTP#セキュリティ]] にしたがって SSMTP を設定した場合、ユーザー {{ic|nobody}} は {{ic|/etc/ssmtp/ssmtp.conf}} にアクセスすることができず、{{ic|systemctl start status-email-user1@dbus.service}} コマンドは失敗します。{{ic|status-email-user1@.service}} モジュールの User に {{ic|root}} を使うことでこれを回避できます。}} |
||
=== crontab を使用する === |
=== crontab を使用する === |
||
− | crontab を使って定期的なサービスを管理するツールとして {{aur|systemd- |
+ | crontab を使って定期的なサービスを管理するツールとして {{aur|systemd-cron-next}} と {{aur|systemd-cron}} があります。どちらも [[AUR]] からインストールすることができます。これらのツールには systemd に存在しない {{ic|MAILTO}} 機能が実装されています。 |
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、{{ic|systemctl}} でそれと同じことが可能です。[[#管理]] を見て下さい。 |
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、{{ic|systemctl}} でそれと同じことが可能です。[[#管理]] を見て下さい。 |
||
+ | |||
+ | === 手動で行う === |
||
+ | |||
+ | 既存の crontab から移行する以外に、cron と同じ周期を使用することが望ましい場合があります。定期的に開始する各サービスのタイマーを作成するという面倒な作業を回避するには、[[systemd#ユニットを使う|テンプレートユニット]] を使用します。例: |
||
+ | |||
+ | {{hc|/etc/systemd/system/monthly@.timer|2= |
||
+ | [Unit] |
||
+ | Description=Monthly Timer for %i service |
||
+ | |||
+ | [Timer] |
||
+ | OnCalendar=*-*-1 02:00:00 |
||
+ | AccuracySec=6h |
||
+ | RandomizedDelaySec=1h |
||
+ | Persistent=true |
||
+ | Unit=%i.service |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=default.target |
||
+ | }} |
||
+ | |||
+ | {{Note|タイマーの起動によってすべてのユニットが同時に開始されるのを避けるために、{{ic|AccuracySec}} だけでなく {{ic|RandomizedDelaySec}} を使用する重要性については、{{man|5|systemd.timer|OPTIONS}} を参照してください。}} |
||
+ | |||
+ | その後、{{ic|monthly@''unit_name''.timer}} を [[起動/有効化]] 行うだけで済みます。 |
||
+ | |||
+ | {{Tip|テンプレートユニットはネストできます。たとえば、{{ic|monthly@btrfs-scrub@mnt-$(systemd-escape bbb76c63-e4ac-4e39-8897-a120c5d30686).timer}} を [[起動/有効化]] することができます。}} |
||
+ | |||
+ | == "有効期間" の処理 == |
||
+ | |||
+ | 一部のソフトウェアは、最後に実行されてからの経過時間を追跡します。たとえば、最後のダウンロードが 24 時間以内に終了した場合はデータベースの更新をブロックします。 |
||
+ | |||
+ | デフォルトでは、タイマーは起動したタスクがいつ終了したかを追跡しません。これを回避するには、{{ic|OnUnitInactiveSeconds}} を使用できます: |
||
+ | |||
+ | {{hc|/etc/systemd/system/daily-inactive@.timer|2= |
||
+ | [Unit] |
||
+ | Description=Launch %i service 24hours after it deactivated |
||
+ | |||
+ | [Timer] |
||
+ | '''OnUnitInactiveSec=1day1sec''' |
||
+ | Unit=%i.service |
||
+ | Persistent=true |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=default.target |
||
+ | }} |
||
+ | |||
+ | {{Tip|{{ic|1=Restart=on-failure}} と {{ic|RestartSec}} を併用すると、失敗と成功の後に異なるスケジュールに従ってユニットを再実行することができます。{{man|5|systemd.service|OPTIONS}} を参照して下さい。}} |
||
== 参照 == |
== 参照 == |
||
+ | * {{man|5|systemd.timer}} |
||
− | * [http://www.freedesktop.org/software/systemd/man/systemd.timer.html systemd.timer man page] on freedesktop.org |
||
* [https://fedoraproject.org/wiki/Features/SystemdCalendarTimers Fedora Project wiki] の ''systemd'' カレンダータイマーのページ |
* [https://fedoraproject.org/wiki/Features/SystemdCalendarTimers Fedora Project wiki] の ''systemd'' カレンダータイマーのページ |
||
* [https://wiki.gentoo.org/wiki/Systemd#Timer_services Gentoo wiki] の ''systemd'' タイマーサービスのセクション |
* [https://wiki.gentoo.org/wiki/Systemd#Timer_services Gentoo wiki] の ''systemd'' タイマーサービスのセクション |
||
− | * {{App|systemd- |
+ | * {{App|systemd-cron-next|crontab と anacrontab ファイルからタイマーとサービスを生成するツール|https://github.com/systemd-cron/systemd-cron-next|{{Aur|systemd-cron-next}}}} |
* {{App|systemd-cron|cron スクリプトを実行する systemd ユニットが入っています。''systemd-crontab-generator'' を使って crontab を変換。|https://github.com/systemd-cron/systemd-cron|{{Aur|systemd-cron}}}} |
* {{App|systemd-cron|cron スクリプトを実行する systemd ユニットが入っています。''systemd-crontab-generator'' を使って crontab を変換。|https://github.com/systemd-cron/systemd-cron|{{Aur|systemd-cron}}}} |
2024年7月10日 (水) 20:53時点における最新版
タイマーは名前が .timer
で終わる systemd のユニットファイルであり、.service
ファイルやイベントを制御します。cron の代わりとしてタイマーを使うことができます (#cron を置き換える を読んで下さい)。タイマーにはカレンダー時刻のイベントとモノトニック時刻のイベントのサポートが入っており、さらに非同期に実行することも可能です。
目次
タイマーユニット
タイマーは拡張子が .timer
の systemd のユニットファイルです。他の ユニット設定ファイル と似ていますが特別に [Timer]
セクションが存在します。[Timer]
セクションにはタイマーが作動する時間と処理を定義します。タイマーには2つのタイプがあり、どちらか一つを使って定義されます:
- モノトニックタイマー は刻々と変わる開始点と相応したタイムスパンの後に作動します。様々なモノトニックタイマーが存在しますがどれも次のような形式です:
OnTypeSec=
OnBootSec
とOnActiveSec
は全てのモノトニックタイマーで共通です。 - リアルタイムタイマー (別名ウォールクロックタイマー) は (cron のジョブと同じように) カレンダーイベントにあわせて作動します。
OnCalendar=
オプションを使って定義を行います。
タイマーのオプションについては systemd.timer(5) の man ページ で説明されています。カレンダーイベントやタイムスパンの引数構文については systemd.time(7) の man ページ で説明されています。
サービスユニット
それぞれの .timer
ファイルには、対応する .service
ファイルが存在します (例: foo.timer
と foo.service
)。.timer
ファイルは .service
ファイルを作動・制御します。.service
に [Install]
セクションは必要ありません。有効にするのは timer ユニットだからです。必要ならば、タイマーの [Timer]
セクションで Unit=
オプションを使うことで別の名前のユニットを制御することもできます。
管理
timer ユニットを使用するには、他のユニットと同じように有効化・起動します。起動しているタイマーを全て表示するには、次を実行:
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
サンプル
タイマーを使用してサービスを実行するのにあたって、service ユニットファイルに変更を加える必要はありません。以下の例では foo.timer
という名前のタイマーを使って foo.service
を定期的に実行します。
モノトニックタイマー
起動15分後に実行され、システムが起動している間、一週間ごとに再度実行されるタイマー:
/etc/systemd/system/foo.timer
[Unit] Description=Run foo weekly and on boot [Timer] OnBootSec=15min OnUnitActiveSec=1w [Install] WantedBy=timers.target
リアルタイムタイマー
一週間ごとに起動するタイマー (月曜日の午前12:00に実行)。システムの電源が切られていたなどの理由で、最後の起動時間を過ぎていた場合、すぐに実行されます (Persistent=true
オプション):
/etc/systemd/system/foo.timer
[Unit] Description=Run foo weekly [Timer] OnCalendar=weekly Persistent=true [Install] WantedBy=timers.target
もっと細かく日時を指定する必要がある場合、次の形式で OnCalendar
イベントを制御できます: DayOfWeek Year-Month-Day Hour:Minute:Second
。アスタリスクをワイルドカードとして使うことができ、カンマで複数の日時を指定することができます。値を ..
で区切ることで連続的に日程を指定することも可能です。
例えば、以下の場合、毎月の1日から4日まで、月曜日か火曜日の場合にのみ、午後0時にサービスを実行します:
OnCalendar=Mon,Tue *-*-01..04 12:00:00
毎月第1土曜日にサービスを実行したい場合は以下のようになります:
OnCalendar=Sat *-*-1..7 18:00:00
毎朝4時に実行したい場合は以下のようになります:
OnCalendar=*-*-* 4:00:00
OnCalendar
は複数指定でき、複数の異なるタイミングでサービスを実行できます。次の例では、平日の22:30および土日の20:00に実行されます:
OnCalendar=Mon..Fri 22:30 OnCalendar=Sat,Sun 20:00
ディレクティブの最後にタイムゾーンを指定することもできます (受け入れられる値をリストするには、timedatectl list-timezones
を使用します。)
OnCalendar=*-*-* 02:00:00 Europe/Paris
詳しくは systemd.time(7) を見てください。
一時的な .timer ユニット
systemd-run
を使うことで一時的な .timer
ユニットを作ることができます。サービスファイルを作成しなくても、特定時刻にコマンドが実行されるように設定することが可能です。例えば、以下のコマンドは30秒後にファイルを作成します:
# systemd-run --on-active=30 /bin/touch /tmp/foo
タイマーファイルが存在しない既存のサービスファイルを指定することもできます。例えば、以下のコマンドは12.5時間後に someunit.service
という名前の systemd ユニットを起動します:
# systemd-run --on-active="12h 30m" --unit someunit.service
詳しくは systemd-run(1) を見てください。
cron を置き換える
おそらく一番有名なジョブスケジューラは cron ですが、systemd のタイマーはその代替手段になりえます。
メリット
タイマーを使う主要なメリットは、それぞれのジョブが固有の systemd サービスを使うというところに根ざします。そのメリットには以下のようなものがあります:
- タイマーとは別個にジョブを実行することが簡単にできます。これによってデバッグが楽になります。
- 特定の環境で動作するようにジョブを設定することができます (systemd.exec(5) man ページを参照)。
- ジョブを cgroups の支配下に置けます。
- 他の systemd ユニットに依存するようにジョブを設定できます。
- systemd の journal でジョブが記録されるのでデバッグが簡単です。
注意事項
cron では簡単にできることが、タイマーユニットを使用する場合、難しかったり不可能であったりすることがいくつか存在します。
- 冗長性: systemd を使って定期的なジョブを設定するには2つのファイルを作成して2回
systemctl
コマンドを実行します。それに対して crontab には一行を追加するだけです。 - メール: ジョブが失敗した時にメールを送信する cron の
MAILTO
と同等なものは存在しません。ただし各サービスにOnFailure=
オプションを使うことで同じような機能を設定することはできます。
MAILTO
Cron の MAILTO
のように、systemd で、ユニットが失敗したときにメールを送信するように設定できます。それにはまず2つのファイルが必要です: メールを送信するための実行可能ファイルと、実行可能ファイルを起動するための .service。以下の例では、sendmail
(smtp-forwarder
を含むパッケージにはすべて含まれています) を使用するシェルスクリプトが実行可能ファイルになっています:
/usr/local/bin/systemd-email
#!/bin/bash /usr/bin/sendmail -t <<ERRMAIL To: $1 From: systemd <root@$HOSTNAME> Subject: $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 $(systemctl status --full "$2") ERRMAIL
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の .service はそれらの引数を渡します:
/etc/systemd/system/status-email-user@.service
[Unit] Description=status email for %i to user [Service] Type=oneshot ExecStart=/usr/local/bin/systemd-email address %i User=nobody Group=systemd-journal
user
はメールを送信するユーザーに、address
はユーザーのメールアドレスに置き換えてください。受信者はハードコードされますが、インスタンスパラメータとしてユニットファイルを渡すことで、上記のサービスだけで他のユニットのメールも送ることができます。status-email-user@dbus.service
を起動して、メールが受け取れることを確認してください。
問題ないようでしたら、メールを送って欲しいユニットの [Unit]
セクションに OnFailure=status-email-user@%n.service
を追加してください。%n
はユニットの名前をテンプレートに指定します。
crontab を使用する
crontab を使って定期的なサービスを管理するツールとして systemd-cron-nextAUR と systemd-cronAUR があります。どちらも AUR からインストールすることができます。これらのツールには systemd に存在しない MAILTO
機能が実装されています。
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、systemctl
でそれと同じことが可能です。#管理 を見て下さい。
手動で行う
既存の crontab から移行する以外に、cron と同じ周期を使用することが望ましい場合があります。定期的に開始する各サービスのタイマーを作成するという面倒な作業を回避するには、テンプレートユニット を使用します。例:
/etc/systemd/system/monthly@.timer
[Unit] Description=Monthly Timer for %i service [Timer] OnCalendar=*-*-1 02:00:00 AccuracySec=6h RandomizedDelaySec=1h Persistent=true Unit=%i.service [Install] WantedBy=default.target
その後、monthly@unit_name.timer
を 起動/有効化 行うだけで済みます。
"有効期間" の処理
一部のソフトウェアは、最後に実行されてからの経過時間を追跡します。たとえば、最後のダウンロードが 24 時間以内に終了した場合はデータベースの更新をブロックします。
デフォルトでは、タイマーは起動したタスクがいつ終了したかを追跡しません。これを回避するには、OnUnitInactiveSeconds
を使用できます:
/etc/systemd/system/daily-inactive@.timer
[Unit] Description=Launch %i service 24hours after it deactivated [Timer] OnUnitInactiveSec=1day1sec Unit=%i.service Persistent=true [Install] WantedBy=default.target
参照
- systemd.timer(5)
- Fedora Project wiki の systemd カレンダータイマーのページ
- Gentoo wiki の systemd タイマーサービスのセクション
- systemd-cron-next — crontab と anacrontab ファイルからタイマーとサービスを生成するツール
- systemd-cron — cron スクリプトを実行する systemd ユニットが入っています。systemd-crontab-generator を使って crontab を変換。