「Systemd/タイマー」の版間の差分
Kusakata.bot (トーク | 投稿記録) 細 (文字列「カスタム .service ファイルを書く」を「ユニットファイル」に置換) |
(同期) |
||
78行目: | 78行目: | ||
WantedBy=timers.target</nowiki>}} |
WantedBy=timers.target</nowiki>}} |
||
− | もっと細かく日時を指定する必要がある場合、次の形式で {{ic|OnCalendar}} イベントを制御できます: {{ic|DayOfWeek Year-Month-Day Hour:Minute:Second}}。アスタリスクをワイルドカードとして使うことができ、カンマで複数の日時を指定することができます。値を {{ic|..}} で区切ることで連続的に日程を指定することも可能です |
+ | もっと細かく日時を指定する必要がある場合、次の形式で {{ic|OnCalendar}} イベントを制御できます: {{ic|DayOfWeek Year-Month-Day Hour:Minute:Second}}。アスタリスクをワイルドカードとして使うことができ、カンマで複数の日時を指定することができます。値を {{ic|..}} で区切ることで連続的に日程を指定することも可能です。 |
+ | |||
+ | 例えば、以下の場合、毎月の1日から4日まで、月曜日か火曜日の場合にのみ、午後0時にサービスを実行します: |
||
OnCalendar=Mon,Tue *-*-01..04 12:00:00 |
OnCalendar=Mon,Tue *-*-01..04 12:00:00 |
||
+ | 毎月第1土曜日にサービスを実行したい場合は以下のようになります: |
||
− | {{Tip|{{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。このような問題は {{ic|RandomizedDelaySec}} オプションを使用してタイマーの起動時間を散らすことで解決できます。{{man|5|systemd.timer}} を参照してください。}} |
||
+ | |||
+ | OnCalendar=Sat *-*-1..7 18:00:00 |
||
+ | |||
+ | 詳しくは {{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"}} のようにコマンドを実行することでテストできます。 |
||
+ | * {{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。このような問題は {{ic|RandomizedDelaySec}} オプションを使用してタイマーの起動時間を散らすことで解決できます。{{man|5|systemd.timer}} を参照してください。}} |
||
=== サービス === |
=== サービス === |
2018年3月31日 (土) 21:50時点における版
タイマーは名前が .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
詳しくは systemd.time(7) を見てください。
サービス
/etc/systemd/system/foo.service
[Unit] Description=daily foo RefuseManualStart=no RefuseManualStop=yes [Service] Type=oneshot ExecStart=/home/<user>/scripts/foo.sh
一時的な .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
を使用するシェルスクリプトが実行可能ファイルになっています:
/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
でそれと同じことが可能です。#管理を見て下さい。
参照
- systemd.timer(5)
- Fedora Project wiki の systemd カレンダータイマーのページ
- Gentoo wiki の systemd タイマーサービスのセクション
- systemd-cron-next — crontab と anacrontab ファイルからタイマーとサービスを生成するツール
- systemd-cron — cron スクリプトを実行する systemd ユニットが入っています。systemd-crontab-generator を使って crontab を変換。