実験1

実験1

3つの異なるフォルダを監視し、そのうちの1つが変更されたらスクリプトを実行してみてください。問題は、スクリプトがどのフォルダが変更されたかを知る必要がありますが、それを渡す方法が見つからないことです。

[Path]
PathChanged=/x/y/z
PathChanged=/a/b/c
PathChanged=/foo/bar
Unit=123.service

[Install]
WantedBy=multi-user.target

私はこれを行う方法がないと仮定しています。そして、3つの別々の.pathファイルがある場合、またはフォルダの1つが変更されるたびに(非効率的で全体的な)スクリプトが3つのフォルダすべてに対して繰り返されるようにする必要があります。

ところで、ここに尋ねなければならないと思いました。おそらく、システム変数が欠落しているか、システムがないより効率的な変数が欠落している可能性があります。それでそこにいますか?

ありがとうございます。

答え1

*.pathいくつかの実験を行った後、最も簡単な方法はパスごとに1つのファイルを使用し、各パスをファイル*@.serviceとしてテンプレート化することです。あなたの例を使用すると、次のようになります。

$ systemctl --user cat 123* *.path
# /home/stew/.config/systemd/user/[email protected]
[Service]
Type=oneshot
ExecStart=/bin/echo %I

# /home/stew/.config/systemd/user/abc.path
[Path]
PathChanged=/a/b/c
[email protected]

# /home/stew/.config/systemd/user/foobar.path
[Path]
PathChanged=/foo/bar
[email protected]

# /home/stew/.config/systemd/user/xyz.path
[Path]
PathChanged=/x/y/z
[email protected]

*.serviceパスは次のようにアクセスできます。%I 指定子

Unit=使用した名前を取得するにはシステム脱出:

$ systemd-escape [email protected] \
      '/x/y/z' \
      '/a/b/c' \
      '/foo/bar'
[email protected] [email protected] [email protected]

関連マニュアルページ:

より簡単な解決策があるかどうか疑問に思ったら、私が試した方法は次のとおりです。


実験1

仮定:環境変数にあります。

システムの実行(5)環境変数のリストを提供します。$RUNTIME_DIRECTORYまたは同じものを設定できます。$LISTEN_FDS

実験設定:

$ mkdir /home/stew/systemdpath
$ systemctl --user cat simplepath.*
# /home/stew/.config/systemd/user/simplepath.path
[Unit]
Description=Path testing

[Path]
DirectoryNotEmpty=/home/stew/systemdpath

# /home/stew/.config/systemd/user/simplepath.service
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/usr/bin/env
$ systemctl --user start simplepath.path

実験結果:

$ touch ~/systemdpath/file
$ journalctl --user simplepath.service
Jul 28 08:26:16 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 08:26:16 stewbian env[334512]: HOME=/home/stew
Jul 28 08:26:16 stewbian env[334512]: LANG=en_GB.UTF-8
Jul 28 08:26:16 stewbian env[334512]: LANGUAGE=en_GB:en
Jul 28 08:26:16 stewbian env[334512]: LOGNAME=stew
Jul 28 08:26:16 stewbian env[334512]: PATH=/home/stew/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Jul 28 08:26:16 stewbian env[334512]: SHELL=/bin/bash
Jul 28 08:26:16 stewbian env[334512]: USER=stew
Jul 28 08:26:16 stewbian env[334512]: XDG_RUNTIME_DIR=/run/user/1000
Jul 28 08:26:16 stewbian env[334512]: GTK_MODULES=gail:atk-bridge
Jul 28 08:26:16 stewbian env[334512]: QT_ACCESSIBILITY=1
Jul 28 08:26:16 stewbian env[334512]: DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
Jul 28 08:26:16 stewbian env[334512]: DESKTOP_SESSION=/usr/share/xsessions/i3
Jul 28 08:26:16 stewbian env[334512]: DISPLAY=:0
Jul 28 08:26:16 stewbian env[334512]: GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
Jul 28 08:26:16 stewbian env[334512]: PAM_KWALLET5_LOGIN=/run/user/1000/kwallet5.socket
Jul 28 08:26:16 stewbian env[334512]: PWD=/home/stew
Jul 28 08:26:16 stewbian env[334512]: SHLVL=1
Jul 28 08:26:16 stewbian env[334512]: XAUTHORITY=/home/stew/.Xauthority
Jul 28 08:26:16 stewbian env[334512]: XDG_CURRENT_DESKTOP=i3
Jul 28 08:26:16 stewbian env[334512]: XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_CLASS=user
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_DESKTOP=i3
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session5
Jul 28 08:26:16 stewbian env[334512]: XDG_SESSION_TYPE=x11
Jul 28 08:26:16 stewbian env[334512]: _=/usr/bin/dbus-update-activation-environment
Jul 28 08:26:16 stewbian env[334512]: MANAGERPID=31634
Jul 28 08:26:16 stewbian env[334512]: INVOCATION_ID=837f6b2e56b543c9b51cda4ee8952fa8
Jul 28 08:26:16 stewbian env[334512]: JOURNAL_STREAM=8:21581980
Jul 28 08:26:16 stewbian systemd[31634]: simplepath.service: Succeeded.
Jul 28 08:26:16 stewbian systemd[31634]: Finished Path testing unit

結論として:

Systemd はパスを環境変数に入れません。


実験2

仮定:テンプレート化可能

$LISTEN_FDSソケットとパスの間にいくつかの類似点があることを検討してください。ソケットは、次の場合にテンプレート化されます。Accept=yes設定されているので、パスを使用しようとするとどうなりますか?

デフォルト設定:

$ systemctl --user cat simplepath*
# /home/stew/.config/systemd/user/simplepath.path
[Unit]
Description=Path testing

[Path]
DirectoryNotEmpty=/home/stew/systemdpath
[email protected]

# /home/stew/.config/systemd/user/[email protected]
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/bin/echo %i

実験結果:

$ systemctl --user start simplepath.path
$ touch ~/systemdpath/file
$ journalctl --user --since "5 minutes ago"
Jul 28 09:14:25 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:14:25 stewbian echo[336171]: simplepath
Jul 28 09:14:25 stewbian systemd[31634]: [email protected]: Succeeded.

結論として

サービスにエコーされたインスタンスはサービス名自体です。それは役に立ちません。


実験3

前提:各パスには独自のファイルとサービステンプレートがあります。

実験設定:

$ mkdir ~/path1
$ mkdir ~/path2
$ systemctl --user cat path*
# /home/stew/.config/systemd/user/path1.path
[Unit]
Description=Path1 testing

[Path]
DirectoryNotEmpty=%h/path1
[email protected]

# /home/stew/.config/systemd/user/path2.path
[Unit]
Description=Path2 testing

[Path]
DirectoryNotEmpty=%h/path2
[email protected]

# /home/stew/.config/systemd/user/[email protected]
[Unit]
Description=Path testing unit

[Service]
Type=oneshot
ExecStart=/bin/echo %h/%i
$ systemctl --user start path1.path path2.path

実験:

$ touch ~/path1
$ touch ~/path2
$ journalctl --user --since "5 minutes ago"
Jul 28 09:43:45 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:43:45 stewbian echo[336517]: /home/stew/path1
Jul 28 09:43:45 stewbian systemd[31634]: [email protected]: Succeeded.
Jul 28 09:43:45 stewbian systemd[31634]: Finished Path testing unit.
Jul 28 09:43:50 stewbian systemd[31634]: Starting Path testing unit...
Jul 28 09:43:50 stewbian echo[336519]: /home/stew/path2
Jul 28 09:43:50 stewbian systemd[31634]: [email protected]: Succeeded.
Jul 28 09:43:50 stewbian systemd[31634]: Finished Path testing unit.

結論として

テンプレートベースのサービス単位を複数のパス単位に適用できます。これは最も簡単な方法のようです。

ここでの問題は、サービスが%hホームディレクトリを使用していることです。/テンプレート名にその文字を含めると問題が発生します。システム脱出(1)この問題を解決するのに役立つようです。

答え2

systemd(RedHat 6.xなど)が導入される前の一部のLinuxでは、systemd.pathソリューションよりもシンプルで完全なincrontabコマンドをインストールして使用できます。 Incrontabとincrondはinotify APIへの強力なインターフェースを提供しますが、残念ながらincrontabと比較して不完全なsystemd.pathに置き換えられます。 incrontab は systemd を使用して現在のバージョンにインストールすることはできますが、現在メンテナンスされていないため、本番システムや重要なシステムには適していません。この問題が今後のバージョンで修正されることを願っています。

関連情報