ファイルにトリガーのようなものを設定して、ファイルが変更されるたびにスクリプトまたはプログラムが実行されるようにする方法はありますか?
シェルスクリプト内でこのメカニズムを見つけただけですが、オペレーティングシステムベースでそのメカニズムがあるかどうかを知りたいのです(バックグラウンドプログラムを手動で実行する必要がないように)。オペレーティングシステムベースのソリューションは、数秒ごとに実行されるcronジョブですが、これは私には適切なソリューションのようには見えません。
ところで、Debian用です。
手伝ってくれてありがとう。
オプションの1つは、Linuxカーネルの inotify サブシステムです。
inotifyは、ファイルシステムを拡張してファイルシステムの変更を通知し、それらの変更をアプリケーションに報告するように機能するLinuxカーネルサブシステムです。
しかし、inotify
はカーネルランドであるため、実際に使用するにはユーザースペースに何かが必要です。
Inotify cronデーモン(incrond)は、ファイルシステムイベントを監視し、システムテーブルとユーザーテーブルで定義されたコマンドを実行するデーモンです。その使用法は一般的にcron(8)に似ています。
Gaminは、FAMのサブセットであるFile AlterationMonitorを独立して実装するファイルとディレクトリの監視システムです。サービスとして実行すると、ファイルまたはディレクトリへの変更を検出できます。 gam_serverは、Gaminのデーモンとして機能します。
inoticoming-ファイルが着信ディレクトリにヒットしたときにアクションをトリガーします
askubuntuに関する同様の質問に対する回答がありました:
これを行うもう1つの手っ取り早い方法は、inotify-toolsパッケージ(Fedora上)のinotifywait
を使用することです。
単一のbashコマンドラインからすべてを実行できるため、この方法の方が好きです。小さなプログラムを書いているときに、保存したものの結果を確認するためにこれをよく使用します。
while [[ 1 ]]; do inotifywait -e modify <filename>; make && ./helloworld; done
シェルスクリプト内のこのメカニズムは完全に適切なソリューションであり、そのメカニズムであると私は主張します。オペレーティングシステムベースで(バックグラウンドプログラムを手動で実行する必要がないように)は、そのソリューションを s6 のようなプロセスマネージャーに配置することを意味します。 )、 runit 、 systemd unit 、または inittabエントリ の場合あなたはsysvinitシステムを使用しています。
それを実行し続けるためのメカニズムに関係なく、私はファイルを監視するための entr が好きです。シンプルで、要点を言えば、構成可能です(たとえば、プロセスマネージャーを配置するのは簡単です)。
/path/to/file
を監視し、変更されたときに/usr/local/bin/do_stuff
を実行するためのスクリプトは次のとおりです。
#!/bin/bash
exec entr /usr/local/bin/do_stuff < <(echo /path/to/file)
これですべてです。それをrunitまたはs6のrun
ファイルに入れるか、systemdユニットのExecStart
行に入れるか、inittab
の行からそのスクリプトを呼び出します。 inittab
に入れる場合は、おそらくどこかにsleep
を追加する必要がありますが、sysvinitは、スペルミスやファイルの欠落などが原因ですぐに失敗するプロセスをレート制限しないためです。
なぜecho /path/to/file | entr /usr/local/bin/do_stuff
だけではないのですか?プロセス管理の下で実行する場合、管理対象プロセスがスーパーバイザーの直下にあることが重要です。これにより、たとえば、シャットダウン。シェルがスーパーバイザーの下で実行されている場合、シェルは実行中のプロセスではなく、TERM
、INT
、またはKILL
シグナルをキャッチし、それらを渡しません。 。または、終了してプロセスを孤立させたままにします。 exec
は、プロセスチェーンからシェルを削除します。 (|
の右側にあるexec
は違いがありません)
または、自分自身を真ん中に置くことのないシェルを使用します execline :
#!/bin/execlineb
pipeline -d {
echo /path/to/file
} entr /usr/local/bin/do_stuff