最近 systemd を crontab 代わりに使うことが多かったが、 よく理解できていなかったので整理した
世間的に2種類のやり方が紹介されていたので、ごっちゃになっていた
方法1
目標は以下のようなミニマムな service を10秒ごとに実行することとする
[Unit]
Description=test
[Service]
ExecStart=bash -c 'date >> /tmp/test.log'
Type=oneshot
[Install]
WantedBy=multi-user.target
これを10秒ごとに実行するために timer ファイルを作成
[Unit]
Description=test timer
[Timer]
OnUnitActiveSec=10s
[Install]
WantedBy=timers.target
これらを systemd に登録し有効化する
sudo systemctl enable ~/services/test.service
sudo systemctl enable ~/services/test.timer
この時点で再起動したら定期実行される
再起動しないで開始したい場合は
sudo systemctl start test.service
sudo systemctl start test.timer
と、どちらもstartしないといけない
1回目はservice自身が起動して、2回目以降はtimerのOnUnitActiveSec=10s
にしたがって、前回の実行の10秒後に行われるという理解でいいだろう
前回の10秒後なので、test.timer
だけstart
しても実行は開始されない
方法2
方法1ではOnUnitActiveSec
の性質上1回目の実行がされなかったがtest.timer
の[Timer]
のところにOnStartupSec=1s
などと追加しておくとtest.timer
をstart
するだけでも定期実行が始まる
[Unit]
Description=test timer
[Timer]
OnStartupSec=1s
OnUnitActiveSec=10s
[Install]
WantedBy=timers.target
この場合は一回目をtest.service
自ら起動する必要がないので、 test.service
の [Install]
の項は削除しても構わない
[Unit]
Description=test
[Service]
ExecStart=bash -c 'date >> /tmp/test.log'
Type=oneshot
[Install]
が無い状態で enable
すると以下のようなワーニングが出てくる
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,Alias= settings in the [Install] section, and DefaultInstance= for template units). This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's .wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer, D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some instance name specified.
[Install]
がないから自動起動設定(enable)できないわけだ
なので、この場合は
sudo systemctl link ~/services/test.service
とするのが多分正しい……けどenable
でもリンクは行われるので問題ないはず
/etc/systemd/system/
以下に直接書いてる場合は何もしなくていい
ファイルを書き換えたら以下のようにして変更を反映させる
sudo systemctl daemon-reload
こちらの方法の場合timerをstartさせるだけで良い
sudo systemctl start test.timer