
でファイルを監視しinotify
、誰かがコンテンツ (IN_MODIFY
またはIN_CLOSE_WRITE
) を変更したときに何らかのコードをトリガーしたいのですが、ユーザーがお気に入りのツールでファイルを編集したときに がイベントを返さなくなるという問題が発生していますinotify
。ファイルは単純なもの (1 行、スペースなし、最大 20 文字) です。使用を制限したくないのですが、さまざまな状況に対処する方法がわかりません。
私が使用しているのinotify
は、さまざまなアプリケーションがファイルを編集するときに受け取るイベントです。
アクション | inotify イベント |
---|---|
touch file |
IN_OPEN |
echo "data" > file |
IN_MODIFY 、IN_OPEN 、IN_ACCESS 、 それからIN_CLOSE_NOWRITE |
nano file (オープン時) |
IN_OPEN |
nano file (の上^O ) |
IN_MODIFY 、、、IN_CLOSE_WRITE IN_OPEN IN_ACCESS |
vim file (オープン時) |
IN_OPEN 、IN_CLOSE_NOWRITE |
vim file (の上:w ) |
IN_MOVE_SELF 、、IN_ATTRIB このファイルからのイベントは停止します |
gedit file (オープン時) |
IN_OPEN 、、IN_CLOSE_NOWRITE IN_ACCESS |
gedit file (保存時) |
IN_OPEN 、、、このファイルからのイベントは停止しIN_CLOSE_WRITE ますIN_ATTRIB |
mv newfile file |
IN_ATTRIB すると、このファイルからのイベントは停止します |
gedit
ある時点で、トリガーもトリガーされてから静かになったように見えましたIN_DELETE_SELF
。
vim
ユーザーがとを使用する場合、ユーザーが編集を完了するとイベントのgedit
取得が停止します。これにはどのように対処すればよいでしょうか?inotify
共通しているのはイベントだけです。イベントを受け取ったら、を実行し、同じパスに基づいて新しい を再作成する必要があるのではないIN_ATTRIB
かと思います。しかし、それが正しいアプローチでしょうか?IN_ATTRIB
inotify_rm_watch()
wd
inotify_add_watch()
もう 1 つのオプションは、親ディレクトリを監視することです。影響を受けるファイル名は に含まれているためinotify_event::name
、対象のファイルでフィルター処理し、 が対象のファイルに一致する場合、IN_MODIFY
またはをトリガーできます。IN_CLOSE_WRITE
name
答え1
ikkachu が述べているように、一部のエディタは新しいファイルを作成し、元のファイルを置き換えて、inode を変更します。つまり、元のウォッチ記述子のウォッチはすべて期限切れになります。
答えは、親ディレクトリを調べて、ターゲット名を持つファイルの変更を確認することです。次のようになります。
namespace fs = std::filesystem;
fs::path path = "./file1";
assert( !path.is_directory() );
int fd = inotify_init();
int wd = inotify_add_watch(
fd,
path.parent_path().c_str(),
IN_MODIFY | IN_CREATE | IN_CLOSE_WRITE
);
...
inotify_event event;
read(fd, &event, BUF_SIZE);
if (wd == event->wd && path.filename() == event->name) {
emit_file_changed();
}
これらのイベント ( ) は、IN_MODIFY|IN_CREATE|IN_CLOSE_WRITE
上で試したテクニック ( touch
、echo "" >
、、) をキャプチャします。これらを使用して、変更されたシンボリック リンクもキャプチャできると思います。vim
nano
gedit
答え2
または、非常に高速で、そのような問題がない fatrace を使用することもできます。たとえば、次のようになります。
fatrace --timestamp --filter='WD<>+'