inotify
を使用してファイルを表示して誰かがコンテンツ(または)を変更したときにいくつかのコードをトリガーしたいのですが、ユーザーがお気に入りのIN_MODIFY
ツールを使用してファイルを編集するとイベントの返却IN_CLOSE_WRITE
が停止する問題が発生しました。inotify
ファイルは単純でなければなりません(1行、スペースなし、最大20文字)。使用を制限したくありませんが、さまざまな状況を処理する方法がわかりません。
私は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
この問題にどのように対処する必要がありますか?
私が見る唯一の共通スレッドはeventsですIN_ATTRIB
。私はイベントを受け取ったらこれを行い、同じパスに基づいて新しいイベントを再作成するIN_ATTRIB
必要があると思います。しかし、これは正しいアプローチですか?inotify_rm_watch()
wd
inotify_add_watch()
別のオプションは、親ディレクトリを監視することです。影響を受けるファイル名が含まれるため、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<>+'