为什么inotifywatch无法检测到添加文件的更改?


14

我正在尝试/tmp使用inotifywatch以下方法监视文件夹中的更改:

sudo inotifywatch -v -r /tmp

创建了几个文件(touch /tmp/test-1 /tmp/test-2)后,我要终止inotifywatch(按Ctrl- C,这将显示以下统计信息:

Establishing watches...
Setting up watch(es) on /tmp
OK, /tmp is now being watched.
Total of 39 watches.
Finished establishing watches, now collecting statistics.
total  attrib  close_write  open  create  filename
8      2       2            2     2       /tmp/

输出仅显示统计信息,而不显示我期望的文件(如herehere)。我尝试了不同类型的访问(通过catmktemp等),但这是同一回事。

我错过了什么?这是因为我正在使用VPS,并且某些内容受到限制吗?

操作系统:VPS上的Debian 7.3(inotify-tools)

Answers:


14

这是由于您使用inotifywatch的方式以及工具本身的工作方式所致。当您运行inotifywatch -r /tmp,你开始看/tmp和所有的文件已经在里面。在内部创建文件时/tmp,目录元数据将更新为包含新文件的inode编号,这意味着更改发生在/tmp,而不是/tmp/test-1。此外,由于启动/tmp/test-1时不在那儿inotifywatch,所以没有inotify手表放在上面。这意味着放置手表后创建的文件上发生的任何事件都不会被检测到。如果您自己看,可能会更好地理解它:

$ inotifywatch -rv /tmp &
Total of n watches.
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

如果启用了跟踪机制inotify_add_watch(2),则最后一条命令将为您设置监视的数量inotifywatch。此数字应与自己指定的数字相同inotifywatch。现在,在其中创建一个文件/tmp并再次检查:

$ inotifywatch -rv /tmp &
Total of n watches.
$ touch /tmp/test1.txt
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

该数字不会增加,这意味着不会监视新文件。请注意,如果您创建目录,则行为是不同的:

$ inotifywatch -rv /tmp &
Total of n watches.
$ mkdir /tmp/test1
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n + 1

这是由于-r开关的行为方式

-r--recursive:[...]如果在监视目录中创建了新目录,则将自动监视它们。

编辑:我收到了你的两个例子之间混淆了一点,但在第一种情况下,该手表是正确放置,因为用户的呼叫inotifywatch~/*(这是扩大了,在这里看到don_crissti的评论)。由于~/.*包含,也会监视主目录~/.。从理论上讲,它还应该包含~/..,与-r开关结合使用,应该可以监视整个系统。

但是,它可能得到的文件触发的名称创建一个监控目录的事件,但我猜inotifywatch不检索该信息(它被保存得更深一些,比目录名)。inotify-tools提供了另一个名为的工具,inotifywait该工具的行为类似于inotify-watch,并提供了更多的输出选项(包括%f,这是您在此处寻找的内容):

inotifywait -m --format "%e %f" /tmp

手册页

--format <fmt>使用类似于printf的语法以用户指定的格式输出。[...]支持以下转换:

%f当目录中发生事件时,它将替换为导致事件发生的文件的名称

%e:用发生的事件替换,以逗号分隔。

此外,-m选项(监视器)将inotifywait在第一个事件后继续运行,这将重现与相似的行为inotifywatch


1
.bashrc在示例中,@ serverfault不会出现在统计信息中,因为用户递归地监视其主目录,但是由于用户目录path/.*已展开,因此为path/.bashrc包括)下的所有.file设置了监视。OP使用的命令将永远不会输出文件名,因为设置了/tmp监视对象,因此任何子目录均仅/tmp与统计信息及其子目录有关(即,您将看到文件已被访问/移动/等,但不会告诉您文件的名称)。名称)。
don_crissti 2014年

@don_crissti糟糕,我混淆了OP给出的两个示例。我编辑了答案,谢谢!
约翰·史密斯

谢谢,这很有用。这是我的命令可显示所有新创建的测试*文件的内容/tmpinotifywait -m --format "%f" /tmp | grep --line-buffered ^test | xargs -L1 -I% sudo cat /tmp/% 2> /dev/null
kenorb 2014年

另外:“ 这意味着将不会检测到放置监视之后在文件上发生的任何事件。 ”由于已为包含目录设置了监视,因此将检测到任何事件(甚至是文件创建)。反映在该特定目录的统计信息中。请参阅inotifywatchOP问题中的输出:存在2个create事件(因此可以检测到它们),但是由于inotifywatch监视目录(+任何子目录),因此统计信息仅与该目录/那些目录有关。
don_crissti 2014年

1
我不认为我们处于同一波长... man inotifyWhen a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.另外,man inotifywatch还清楚正在监视哪些事件:EVENTS>> ... 已访问/关闭/打开/打开了受监视文件或受监视目录中的文件等等(意味着包括“发生在文件上”的事件)。将监视设置为父目录后创建的文件的事件将被检测并反映在inotifywatch统计信息中(不会提及那些事件发生在哪些文件上)。
don_crissti 2014年
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.