systemd でパス監視機能を使う
systemd.path を試していきます。
パスの監視というと理解しくいかもしれませんが、フォルダの監視です。フォルダを監視してなんかやります。もちろんファイルも監視できます。
inotify でアプリを書くより手軽です。
はじめに
systemd でパスを監視することができる。
xxxx.path と xxxx.service をペアで作成し登録すればオッケ。
制限事項
再帰的(recursive)なパス監視はできない。
inotify を使っているので、 nfsなどネットワーク越しでは使えない。
gvfs/gio でマウントしていると inotifyが発動するはずなので cifs でもつかそう
ユーザー空間にファイルを作って作って試す
今回は、次のファイルを作って試していきます。
~/.config/systemd/user/desktop.service ~/.config/systemd/user/desktop.path
systemd のユーザー空間について、過去の資料を参考に
~/.config/systemd/user/desktop.service
[Unit] Description=DesktopSample [Service] WorkingDirectory=/home/takuya/Desktop ExecStart=/bin/echo Hello From Service [Install] WantedBy=default.target
~/.config/systemd/user/desktop.path
[Unit] Description=DesktopSample [Path] ## PathModified と PathChanged は別物 ## 再帰的( recursively ) にパスの監視はできない。 ## inotify をベースにしている PathChanged=/home/takuya/Desktop #PathModified=/home/takuya/Desktop [Install] WantedBy=default.target
ロードする
systemctl --user daemon-reload
起動する
enable して
systemctl --user enable desktop.service systemctl --user enable desktop.path
restart しておく
systemctl --user restart desktop.service systemctl --user restart desktop.path
コレで起動するので、あとはログを見ながら、動作する様子を見る
journalctl でログを開いておく
path の監視が起動したときのログ
journalctl --user -f -u desktop.path
service が起動したときのログ
journalctl --user -f -u desktop.service
-f
をつけているので、ログは tailf と同じく following される。
動作を実験してみる。
いくつか、ファイルを作成したり、ファイルを更新したりして パスを書き換える実験をしておく
cd ~/Desktop/ echo 更新テスト > a echo 更新テスト2 > a echo 更新テスト3 > a echo 更新テスト4 >> a echo 更新テスト5 >> a rm a touch a chmod 777 a rm a mkdir a rmdir a
あとは、ログを見ながら、このタイミングでイベント発火するとか確認しておけばいい。
再帰的監視はできない
代わりに、PathChanged を複数書くことができます。
このように複数書くことができます。
[Path] PathChanged=/home/takuya/Desktop PathChanged=/home/takuya/Desktop/.hidden PathChanged=/home/takuya/Desktop/.gitignore PathChanged=/home/takuya/Desktop/.git
更新について
PathModifiedとPathChanged がある。man systemd.path を見るとあれこれ書いてある。
PathChanged について
PathChanged= may be used to watch a file or directory and activate the configured unit whenever it changes. It is not activated on every write to the watched file but it is activated if the file which was open for writing gets closed.
PathModified については
PathModified= is similar, but additionally it is activated also on simple writes to the watched file.
たぶん、次のようなことだと思う。 - PathChanged は open → close されたら発動 - PathModified append された発動
open されたまま、追記されていくデータファイルやログファイルを追いかけるでもない限り PathChanged で問題ないと思われる。
その他の監視モード
- パスが存在したらなにかする。
- パスに変更がアレばなにかする。
- ディレクトリが空っぽ以外になったらなにかする。
- ファイルを指定をglob でやる
などがある。それぞれ次の名前で定義されている
PathExists=, PathExistsGlob=, PathChanged=, PathModified=, DirectoryNotEmpty=
簡単に実装できて便利。
「できる」だけであり、痒いところまで手が届くような使い勝手がいいものではない。
ただ、systemd のユーザー空間と組み合わせて、ユーザー空間で独自にぱぱっと関する程度ならお手軽でいいと思う。
細かい部分まで実装したいなどの用途に向かない。
例えば、ファイルが新規作成された、更新された、truncate されたとか、ディレクトリ内部に作成されたファイル名が知りたい。などなど。 細かい点について作業をしたいもののが欲しいなら inotify 系の python や npm/fsevent 系を使って細々書いておき、書いたpython を service 化するほうがずっといいだろうな。
systemd.path はgnome デスクトップなどで作成されるファイルを手軽に監視して同期したいなどで重宝すると思います。
参考資料
- man systemd.path