私はあなたのアプローチは正しいと思います、そしてクッキーを追跡することはこれを行う強力な方法です。ただし、cookie
参照されるinotify-tools(3.14)のソース内の唯一の場所はstruct
、カーネルAPIと一致するように定義するヘッダー内です。
エッジに住むのが好きな場合、このパッチ(問題#72)は3.14にきれいに適用%c
され、イベントCookieのフォーマット指定子を16進数で追加します。
--- libinotifytools/src/inotifytools.c.orig 2014-10-23 18:05:24.000000000 +0100
+++ libinotifytools/src/inotifytools.c 2014-10-23 18:15:47.000000000 +0100
@@ -1881,6 +1881,12 @@
continue;
}
+ if ( ch1 == 'c' ) {
+ ind += snprintf( &out[ind], size-ind, "%x", event->cookie);
+ ++i;
+ continue;
+ }
+
if ( ch1 == 'e' ) {
eventstr = inotifytools_event_to_str( event->mask );
strncpy( &out[ind], eventstr, size - ind );
この変更によりlibinotifytools.so
、inotifywait
バイナリではなくが変更されます。インストール前にテストするには:
LD_PRELOAD=./libinotifytools/src/.libs/libinotifytools.so.0.4.1 \
inotifywait --format="%c %e %f" -m -e move /tmp/test
Setting up watches.
Watches established.
40ff8 MOVED_FROM b
40ff8 MOVED_TO a
MOVED_FROMは常にMOVED_TO前に発生したと仮定すると(それは、見ないfsnotify_move()
、そしてそれはだ注文キューの独立した動きがけれども、かもしれない、あなたは(おそらくIDでインデックス化連想配列で)MOVED_FROMラインを見ると、あなたが詳細をキャッシュするスクリプトでインターリーブます)そして、情報の半分が一致するMOVED_TOが表示されたら、処理を実行します。
declare -A cache
inotifywait --format="%c %e %f" -m -e move /tmp/test |
while read id event file; do
if [ "$event" = "MOVED_FROM" ]; then
cache[$id]=$file
fi
if [ "$event" = "MOVED_TO" ]; then
if [ "${cache[$id]}" ]; then
echo "processing ..."
unset cache[$id]
else
echo "mismatch for $id"
fi
fi
done
(3つのスレッドが実行されて10,000回ずつファイルのペアをシャッフルするので、1つの順序の乱れたイベントやイベントインターリーブを見たことはありません。もちろん、ファイルシステムや他の条件に依存する場合があります。)