rcmdnk's blog

【正規品】TIME TIMER タイムタイマー 19cm 60分 TTA1-W 時間管理

Raspberry Piで定期的に実行したいジョブがあったので cronジョブとして実行しようかと思ってましたが、 systemdで定期実行する、ということをやってみたかったので systemdでやってみることにしました。

やりたいこと

cronジョブで書けば

0 12 * * * /path/to/script

みたいな感じで毎日お昼の12:00に実行するようなもの。

これを最近Linuxでは主に使われているサービス管理システムであるsystemdを使って作る、というもの。

実行用サービスの準備

これをやるために、まず以下の様なサービスを用意します。

/etc/systemd/system/myjob.service
1
2
3
4
5
6
7
8
9
[Unit]
Description = My Job

[Service]
Type = oneshot
ExecStart = /path/to/myjob

[Install]
WantedBy = multi-user.target

Typeに関しては、このジョブはタイマーで起動し、一回限り、 終わったら終了、というものにしたいのでoneshotに。 oneshotExecStartのコマンドが終了したら起動完了、として通知します。

通常使うsimpleにするとExexStartを実行した時点で起動完了として、 通常そのまま生き続ける様なものに使います。

WantedBymulti-user.targetを指定して 通常の起動でGUIがない場合でも有効にする、 という指定で、これは他のサービスでもだいたい同じ様に設定するものです。

Timerサービスの準備

次に上のサービスを定期的に実行するタイマーを作ります。

/etc/systemd/system/myjob.timer
1
2
3
4
5
6
7
8
9
[Unit]
Description = My Job Timer

[Timer]
OnCalendar = *-*-* 12:00:00
AccuracySec = 1s

[Install]
WantedBy = timers.target

こんな感じ。

まず、InstallのセクションでWantedBytimers.targetを指定しています。

これによってタイマーとしてジョブを起動するようになります。 後はタイマーの定義をTimerセクションで行います。

OnCalendar = *-*-* 12:00:00

で毎日12時に実行、になります。 cronジョブとは逆で普通な感じで年-月-日 時:分:秒と書いてあります。

cronのように1,2,3で1,2,3のとき、1..5みたいな書き方で1~5、0/5で5置き、という書き方も各項目で出来ます。

曜日もSun 20:00:00みたいな感じで日曜の20時に、という指定も可能。 Mon,Wedで複数にしたり、Mon..Friで月曜から金曜、というのも可能。

それら以外にweeklydailyhourlyといった任意の時間に定期的に実行する、という指定も可能。

AccuracySec1sで1秒、と設定していますが、 デフォルトでこの値は1mで1分です。

この値の範囲内に始まる、ということなので、 デフォルトでは12:00:00に設定すると12:01:00までの間のどこかで始まる、ということになります。

ちょっと正確に時間を使いたかったので1秒にしてありますが、 最小で1us(1マイクロ秒)まで小さく出来ます。

一方、これを小さくすればするほど時間を管理するためにCPU利用率が上がるので 最大限許容範囲で大きくした方が良いとのこと。 ジョブ自体が数秒かかるものだったりミリ秒以下の必要がなかったので1sにしてあります。

ただ、Raspberry Pi Zeroで1usで動かしていても目に見えたCPU利用率の変化はありませんでした。

タイマー内で呼び出すサービスを指定していませんが この場合は同じディレクトリにある同じ名前のサービスを呼び出します。 今回はmyjob.servicemyjob.timer、とサービスとタイマーが同じ名前のため myjob.serviceが呼び出される、ということに。

もし、別のサービスを呼び出したい場合には、

/etc/systemd/system/myjob.timer
1
2
3
4
5
6
7
8
9
10
[Unit]
Description = My Job Timer

[Timer]
OnCalendar = *-*-* 12:00:00
AccuracySec = 1s
Unit = yourjob.service

[Install]
WantedBy = timers.target

の様な感じでTimerセクションの中にUnitという変数を入れて そこにサービス名を指定します。

登録

myjob.servicemyjob.timer の2つのファイルを /etc/systemd/system/に入れて

$ sudo systemctl daemon-reload
$ sudo systemctl enable myjob.timer
$ sudo systemctl start myjob.timer

で有効にしてスタート。

cronジョブとの違い

cronジョブと違って良い点は

  • 秒単位で指定ができる
  • 他のsystemdユニットへの依存関係が使える
  • runレベルの指定ができる
  • systemdでの管理で簡単に有効、無効化ができる
  • journaldでログが管理できる
  • cgroupsで管理できる

悪い点としては

  • 1つのスクリプトを実行したいだけでも2つのファイルが必要で内容も多くなってしまう
  • メールで通知したい場合、結構面倒
    • メール通知用スクリプト、それを実行するType = oneshotなサービスを別途用意してUnitセクションにOnFailure=<service>のような形で設定する

という感じ。 なのでやはり単純に1つのスクリプトをさっと定期実行設定したい、という場合にはcronの方が簡単です。

システムを構築するような場合、きちんと設計したい場合には systemdを使ったほうが管理が簡単になる可能性はありますし、 より詳細に管理が出来ます。

ユーザーレベルジョブ

ユーザーレベルでの設定をsystemdで行うことも出来て、

~/.config/systemd/user/

ディレクトリにサービス/タイマーファイルを入れて、

$ systemctl --user enable myjob.timer

などとすればOK。

まとめ

cronジョブの代わりとしてsystemdを使おうと思った場合、 やはり少し覚えることも多く、敷居としては高い感じはしました。

その代わり詳細な時間設定や他のサービスとの連携もきちんと取れるようになるので、 システム管理として何らかのジョブを定期的に走らせたい、 という場合にはsystemdを使ったほうが便利だし、 慣れれば設定したり管理するのもむしろ楽になるかと思います。

システム管理をしよう、と思うくらいであればそれほど難しいものではないし いずれにしろ知っておかなくちゃいけないことだったりもするので。

macOSの方でも、cronジョブは使えますが、macOSの機能としてlaunchdという サービス管理をするシステムがあり、 これを使ってcron的な定期ジョブを実行することが出来ます。

これもsystemd同様、よりシステムに親和性の高い管理ができるという点で利点がありますが、 やはり必要な記述量が多いのでちょっとしきい値が高いものではあります。

Sponsored Links
Sponsored Links

« NatureRemo APIとGASを使って温度や家電の状態をGoogle Spreadsheetsに保存する Raspberry Piで測定した温度湿度気圧をGoogle Spreadsheetsに記録する »