それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

systemd.path で path(パス) を監視する。

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

関連資料

https://takuya-1st.hatenablog.jp/entry/2019/08/09/004829