我认为您的方法是正确的,并且跟踪cookie是执行此操作的可靠方法。但是,在inotify-tools(3.14)源中唯一cookie
被引用的地方是在标头中定义了struct
与内核API匹配的标头。
如果您喜欢生活在边缘,则此补丁(问题#72)完全适用于3.14,并%c
以十六进制形式添加了事件cookie 的格式说明符:
--- 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()
,并且它是有序队列,尽管可能会交错插入独立的动作),当您看到MOVED_FROM行(可能在ID索引的关联数组中)时,缓存了详细信息,并在看到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
(通过运行三个线程来每10,000次随机播放一对文件,我从未见过单个乱序事件或事件交织。这当然取决于文件系统和其他条件。)