Inotify 具有一定深度的监控子目录?

Posted

技术标签:

【中文标题】Inotify 具有一定深度的监控子目录?【英文标题】:Inotify monitor sub-directories with certain depth? 【发布时间】:2016-07-12 17:25:05 【问题描述】:

是否可以通过 inotify 将新创建的子目录中的文件监控到一定级别?

假设有一个结构:

/home/user1/data
/home/user2/data
...

定期添加新用户。

我们只想监控“data”目录中的数据,但不想监控新创建的子目录中的数据,例如如果用户创建“/home/user3/data/test_uploads”,则不应该进行处理。

如果我们使用以下语法的 inotifywait,它将只检查现有目录:

inotifywait -m -e close_write /home/*/data/

如果我们在 /home 中创建新用户,它不会被处理,因为 inotify 只扫描现有目录。

有什么方法可以将新添加的目录监控到一定级别,但不使用"-r"选项,因为它会监控所有子目录?

提前致谢!

【问题讨论】:

添加用户是什么系统?什么系统正在将文件添加到数据目录? There may be a better way to solve your problem than the solution you're asking for help implementing. 【参考方案1】:

inotifywait--exclude 选项,但不幸的是它没有--include 选项并且它不支持扩展的POSIX 正则表达式,因此不能只包含文件不匹配 给定模式。详情见this answer。

其他选项:

您可以只输出inotifywaitgrep,但这样就无法避免监控所有不必要的子文件的开销。

您可以使用已修补的inotifywait--include 选项,如上面链接的答案中所述。

您可以直接使用inotify API 编写您自己的程序,这样您就可以控制监控哪些文件以及排除哪些文件。也有各种脚本语言的绑定,包括 Python。

您可以使用各种 inotify 包装器,例如watchdog Python 模块。


这是一个使用 watchdog Python 模块和来自其仓库的 watchdemo.py 脚本的示例。

启动监视器:

$ python2 watchdemo.py shell-command \
    --recursive \
    --pattern='/home/*/data/*' \
    --ignore-pattern='/home/*/data/*/*' \
    --ignore-directories \
    --command='echo "$watch_event_type $watch_src_path"' \
    /home

创建文件和目录:

$ mkdir -p /home/user/data
$ touch /home/user/foo
$ touch /home/user/data/bar
$ mkdir /home/user/data/baz
$ touch /home/user/data/baz/qux

监视器输出将是:

created /home/user/data/bar
modified /home/user/data/bar

请注意,/home/user/foo/home/user/data/baz/qux 不匹配。

如果需要按类型过滤事件:

如果您使用的是watchdemo.py,请检查 shell 命令中的类型:

... \
--command='[ "$watch_event_type" = created ] && echo "$watch_src_path"'

如果您直接使用watchdog Python 模块,请从FileSystemEventHandler 派生自定义事件处理程序并覆盖所需的方法,例如on_created.

【讨论】:

谢谢你,真的很有用!这种方法有两个问题:1)是否有可能以某种方式只监视“创建”事件,而没有“修改”?目标是在创建文件时只通知一次 2) 如果我为 --pattern='/home/*/data/*' 而不是 --pattern='./*/data/*' 放置完整路径,它不起作用,不知道为什么?提前致谢! 对于 1),请参阅更新后的答案。对于 2),尝试使用绝对路径的 watchdemo 的 --directory 选项 谢谢!第一个选项工作得很好,它正在显示“创建”事件。但是第二个目录不起作用,我尝试使用 --directory 并且它无法识别标志,看起来它不存在。我尝试使用选项“directories /home/user”,但出现错误“OSError:Path is not a directory”。目录指令似乎有问题 @Igor 我的错。目录作为位置参数传递给watchdemo,没有选项。查看更新的答案。 嗨@gavv,看起来这种方法存在问题,因为在文件实际关闭之前文件被报告为“已创建”。结果,它正在处理实际上没有完全写入的文件。有什么办法只有在文件完全写入和关闭后才能处理?

以上是关于Inotify 具有一定深度的监控子目录?的主要内容,如果未能解决你的问题,请参考以下文章

inotify,inotify_add_watch() 监控多个目录,c++

在linux下使用inotify监控,能不能够知道监控目录下子目录中是哪个文件被修改了。。。求方法。。。

inotify机制监控文件系统事件原理及使用

Linux下inotify的基本使用及注意事项

bash & inotify - 监控和移动文件

linux使用inotify+rsync实现监控目录变化