为什么inotify事件会触发多次


13

这个问题来自于我对Stackoverflow提出的另一个问题。我使用的守望者 -同样的问题也适用于Incron -监视文件夹,更改和默默离开松鼠这些更改的Dropbox其子文件夹。

我监视write_close事件-- IN_CLOSE_WRITE为此。最初,我正在观看modify事件,即IN_MODIFY。在此过程中,我发现写入大型文件时会触发多次。听起来很公平,所以我转而去,IN_CLOSE_WRITE因为我觉得假设一个给定的文件只会出现一次是很合理的。

但是,事实并非如此。即使对于在Nano中创建的非常小的文本文件(只有一个字符),事件也会发生两次。最好是,当同一文件在Dropbox上同步两次时,这可能会导致不必要的流量。就我自己而言,这会导致灾难,因为在第一个事件中,我执行同步,然后删除服务器端文件。结果-在第二个事件中,Dropbox侧文件变为0字节文件。

我现在通过在执行其他任何操作之前使同步脚本休眠10秒钟来解决此问题,然后在尝试Dropbox同步之前检查相关文件是否仍然存在。之所以有效,是因为在第二次迭代中文件丢失并且脚本刚刚终止。

充其量听起来好像很黑。也许这不是一个糟糕的技巧,但我更希望理解-为什么连IN_CLOSE_WRITE事件都发生不止一次?


一些其他信息

  • 检查以确保没有多个观察程序实例在运行。

来自的输出 ps ax|grep watcher.py

23880 ?        Sl     0:01 python /usr/local/bin/watcher.py restart
24977 pts/0    S+     0:00 grep --color=auto watcher.py

文件系统是ext4。我应该提到,我在Incron遇到了完全相同的问题。我从通过执行的批处理脚本启动Watcher守护程序/etc/rc2.d。Incron OTH通过其默认apt-get install incron安装启动时,我丝毫不为所动。


我的watcher.ini文件的实质如下所示。

[DEFAULT]
logfile=/var/log/watcher.log
pidfile=/var/run/watcher.pid

[job1]
watch=/path/to/watch

events=write_close
excluded=
recursive=true
autoadd=true

command=/home/datastore.php $filename

我将datastore.php脚本简化为最基本的内容,以验证是否在没有任何混乱的Dropbox上传和源代码删除代码的情况下启动了两次脚本。

#! /usr/bin/php
<?php
file_put_contents('/tmp/watcher',$argv[1],FILE_APPEND);

?>

然后,我在所讨论的路径上创建了一个小文件,然后进行了检查/tmp/watcher。问题仍然存在-该文件仍具有两个连续的条目$argv[1]


1
我尝试了许多变体,但是无法通过多次IN_CLOSE_WRITE触发来复制您的问题。我所做的任何事情都会导致单个inotify输出。我将继续尝试。但是到目前为止,只有问题。哪个文件系统?Ext4?其他?
lornix

@lornix-请参阅我的问题的编辑内容。文件系统是,ext4而且我可以肯定地确定我没有两个Watcher实例正在运行。我在Incron遇到了同样的问题。
DroidOS

您说“我执行同步,然后删除服务器端文件”。此删除是否触发第二个事件?您可以禁用delete常规并重试吗?
Germar

@Germar-看到我的问题的编辑。即使同步脚本不进行真正的同步也没有unlink问题,但问题仍然存在
DroidOS

抱歉,出于想法的考虑,我无法在任何计算机上重现该问题。我得到一个事件,没有更多。还涉及其他一些东西,没有提到。您是否安装了防病毒软件?这样的事吗
lornix

Answers:


1

我不确定,但是很可能第一个write_close将文件属性写入其中,例如创建时间,并且只有在此之后才写入实际数据。实际上,rsync会创建一个临时文件,当所有操作完成后,它将临时文件移至同一文件夹中的实际文件,因此使用rsync时通常已经创建了易于监视的文件,而move是原子操作。另一方面,在inotify中有一个被调用的东西,可能是使用它可以在第一个修改消息上触发一些东西,并且如您所建议的,在开始操作之前要睡眠一段合理的时间。我现在正在对此进行挖掘,当我发现新内容时会进行更新。 /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


您可能已经将手指放在这里相当有效的地方。这将需要一些调查。谢谢你的提示。如果发现这是一个问题,我将回发。
DroidOS

我认为ATTRIB不会向文件本身添加任何内容,我错了。
Edik Mkoyan

0

我没有足够的代表将此评论发表,但是您确定没有创建可能隐藏的临时文件吗?我inotifywait多次触发有一个类似的问题,但是我意识到这是因为vim在编辑时会创建一个.swp文件,而在关闭时会触发一个事件。它还将从原始文件中获取关闭事件。

听起来您好像注意到了在同一文件上触发多个文件的事件,这不是我能够复制的东西-对于临时文件只会发生一次,对于原始文件只会发生一次。

我尝试使用nano进行快速测试,但我认为它根本不会创建临时文件(至少对于少数字符而言),但是您的设置中是否还有其他依赖类似行为的内容?


谢谢您的建议。即使使用Nano创建一个非常琐碎的1字节文件,甚至只是将控制台中的单个char重定向到文件中,我都遇到了inotify多个问题。我在原始问题中概述的“解决方案”让我暂时坚持下去。但是,从长远来看,我唯一需要从头开始重建服务器以识别错误开始的解决方案-我与Incron,Watcher的安装(顺便说一下,当我只有Incron时就发生了),MariaDB,Nginx,Redis,Memcached ...并非完全是“简单”的。
DroidOS '16

以防万一,请再次检查您是否没有两次监视同一文件夹。如果不是,那么例如当我通过os x samba客户端将文件复制到samba共享时,就会发生create,close_write,delete,create,close_write当我使用Windows客户端执行此操作时,create,write_close看​​起来更合理,仅此而已。因此,通过使用此IN_MODIFY,IN_ONESHOT /目录监视文件的第一次修改来解决我的问题。睡眠someTime命令oneshot可完成此操作。
Edik Mkoyan '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.