如何在 Linux 中监视完整目录树的变化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8699293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to monitor a complete directory tree for changes in Linux?
提问by Udo G
How can I monitor a whole directory treefor changes in Linux (ext3file system)?
如何在 Linux(ext3文件系统)中监视整个目录树的变化?
Currently the directory contains about half a million filesin about 3,000 subdirectories, organized in three directory levels.
目前,该目录在大约3,000 个子目录中包含大约50 万个文件,分为三个目录级别。
Those are mostly small files (< 1kb, some few up to 100 kb). It's a sort of queue and I need to know when files are being created, deleted or their content modified within 5-10 seconds of that happening.
这些大多是小文件(< 1kb,少数可达 100 kb)。这是一种队列,我需要知道在 5-10 秒内创建、删除文件或修改其内容的时间。
I know there is inotifyand sorts, but AFAIK they only monitor a single directory, which means I would need 3,000 inotify handles in my case - more than the usual 1024 handles allowed for a single process. Or am I wrong?
我知道有inotify和 sorts,但 AFAIK 他们只监控一个目录,这意味着在我的情况下我需要 3,000 个 inotify 句柄 - 比通常的单个进程允许的 1024 个句柄多。还是我错了?
In case the Linux system can't tell me what I need: perhaps there is a FUSEproject that simulates a file system (replicating all file accesses on a real file system) and separately logs all modifications (couldn't fine one)?
如果 Linux 系统不能告诉我我需要什么:也许有一个FUSE项目可以模拟文件系统(在真实文件系统上复制所有文件访问)并单独记录所有修改(不能很好)?
采纳答案by Frédéric Hamidi
To my knowledge, there's no other way than recursively setting an inotify
watch on each directory.
据我所知,除了inotify
在每个目录上递归设置监视之外别无他法。
That said, you won't run out of file descriptors because inotify
does not have to reserve an fd to watch a file or a directory (its predecessor, dnotify
, did suffer from this limitation). inotify
uses "watch descriptors" instead.
也就是说,您不会用完文件描述符,因为inotify
不必保留 fd 来监视文件或目录(它的前身dnotify
,确实受到此限制)。inotify
改为使用“观察描述符”。
According to the documentation for inotifywatch, the default limit is 8192 watch descriptors, and you can increase it by writing the new value to /proc/sys/fs/inotify/max_user_watches
.
根据inotifywatch的文档,默认限制是 8192 个监视描述符,您可以通过将新值写入 来增加它/proc/sys/fs/inotify/max_user_watches
。
回答by j?rgensen
Wasn't fanotify supposed to provide that capability eventually? Quoting LWN:
难道 fanotify 最终不应该提供这种能力吗?引用LWN:
“fanotify has two basic 'modes' directed and global. [...] fanotify global instead indicates that it wants everything on the system and then individually marks inodes that it doesn't care about.”
“ fanotify 有两种基本的“模式”定向和全局。[...] fanotify global 表示它需要系统上的所有内容,然后单独标记它不关心的 inode。”
I lost track what its latest status was, though.
不过,我忘记了它的最新状态。
回答by Jason Miesionczek
I've done something similar using the inotifywait
tool:
我使用该inotifywait
工具做了类似的事情:
#!/bin/bash
while true; do
inotifywait -e modify,create,delete -r /path/to/your/dir && \
<some command to execute when a file event is recorded>
done
This will setup recursive directory watches on the entire tree and allow you to execute a command when something changes. If you just want to view the changes, you can add the -m
flag to put it into monitor mode.
这将在整个树上设置递归目录监视,并允许您在发生变化时执行命令。如果您只想查看更改,可以添加-m
标志以将其置于监视模式。
回答by Madan Kumar
$ inotifywait -m -r /path/to/your/directory
This command is enough to watch the directory recursively for all events such as access, open, create, delete ...
这个命令足以递归地观察目录的所有事件,例如访问、打开、创建、删除......
回答by Smeterlink
Use inotifywait from inotify-tools:
使用 inotify-tools 中的 inotifywait:
sudo apt install inotify-tools
sudo apt install inotify-tools
Now create a script myscript.sh
that includes hidden files and folders too:
现在创建一个myscript.sh
包含隐藏文件和文件夹的脚本:
#!/bin/bash
while true; do
inotifywait -e modify,create,delete,move -r
done
Make the script executable with chmod +x myscript.sh
使脚本可执行 chmod +x myscript.sh
Run it with ./myscript.sh /folder/to/monitor
运行它 ./myscript.sh /folder/to/monitor
If you don't provide argument it will use the working directory by default.
如果您不提供参数,它将默认使用工作目录。
Also, you can run several commands adding && \
at the end of the previous command to add the next one:
此外,您可以运行多个命令添加&& \
在上一个命令的末尾以添加下一个:
#!/bin/bash
while true; do
inotifywait -e modify,create,delete,move -r && \
echo "event" && \
echo "event 2"
done
If you don't want to execute any command on events, just run the command directly with the -m
modifier so doesn't close:
如果您不想对事件执行任何命令,只需使用-m
修饰符直接运行该命令,这样就不会关闭:
inotifywait -e modify,create,delete,move -m -r /path/to/your/dir
inotifywait -e modify,create,delete,move -m -r /path/to/your/dir
回答by fmassica
inotify is the best option when you have many subdirectories but if not I am used to using this command below:
当您有许多子目录时,inotify 是最佳选择,但如果没有,我习惯于使用以下命令:
watch -d find <<path>>
watch -d find <<path>>