USB機器を挿した契機で、ちょっと時間のかかるプログラムをバックグラウンドで起動したい。
そのまま呼ぶと一瞬で殺されるので、systemdを使って起動する
/etc/udev/rules.d/99-local-usb.rules
# USB機器が刺さったらなんかする #ACTION=="add" , SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", RUN+="/usr/local/bin/hoge.sh" ACTION=="add" , SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hoge.service"
/etc/systemd/system/hoge.service
[Unit] Description=HOGEHOGE service #After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/hoge.sh [Install] WantedBy=multi-user.target
Linux でデバイスを接続している時だけ動くサービスを作る - Qiita
access.redhat.com
ユニットに引数を渡したい
systemd経由でプログラムを呼ぶと、環境変数がないので 何がどこにどう刺さったかなどが全然わからない。
テンプレートユニットを使うと、引数をいっこだけ渡すことができる。
ファイル名を hoge@service とすると自動的にテンプレートユニットになり、SYSTEM_WANTS に足していく際、@の後ろにひとつだけ引数を渡すことができる。
ただし、空白は使えないし - が / に置換されてしまうしほかにも制約が多い
/etc/udev/rules.d/99-local-usb.rules
# USB機器が刺さったらなんかする ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hoge@%E{DEVPATH}.service"
/etc/systemd/system/hoge@.service
[Unit] Description=HOGEHOGE service %I #After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/hoge.sh %I [Install] WantedBy=multi-user.target