Linux 使用inotify的正确方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4062806/
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
What is the proper way to use inotify?
提问by dubila
I want to use the inotify
mechanism on Linux. I want my application to know when a file aaa
was changed. Can you please provide me with a sample how to do that?
我想inotify
在 Linux 上使用该机制。我希望我的应用程序知道文件何时aaa
更改。你能给我提供一个如何做到这一点的样本吗?
采纳答案by joschi
- Documentation ( from Monitor file system activity with inotify)
- 文档(来自使用 inotify 监控文件系统活动)
The inotify
C API
在inotify
C API
inotify
provides three system calls to build file system monitors of all kinds:
inotify
提供三个系统调用来构建各种文件系统监视器:
inotify_init()
creates an instance of theinotify
subsystem in the kernel and returns a file descriptor on success and-1
on failure. Like other system calls, ifinotify_init()
fails, checkerrno
for diagnostics.inotify_add_watch()
, as its name implies, adds a watch. Each watch must provide a pathname and a list of pertinent events, where each event is specified by a constant, such asIN_MODIFY
. To monitor more than one event, simply use the logical or — the pipe (|) operator in C—between each event. Ifinotify_add_watch()
succeeds, the call returns a unique identifier for the registered watch; otherwise, it returns-1
. Use the identifier to alter or remove the associated watch.inotify_rm_watch()
removes a watch.
inotify_init()
inotify
在内核中创建子系统的一个实例,并在成功和-1
失败时返回一个文件描述符。与其他系统调用一样,如果inotify_init()
失败,请检查errno
诊断信息。inotify_add_watch()
顾名思义,增加了一个watch。每个监视必须提供一个路径名和一个相关事件列表,其中每个事件都由一个常量指定,例如IN_MODIFY
. 要监视多个事件,只需在每个事件之间使用逻辑或——C 中的管道 (|) 运算符。如果inotify_add_watch()
成功,调用返回注册手表的唯一标识符;否则,它返回-1
。使用标识符来更改或删除关联的手表。inotify_rm_watch()
移除手表。
The read()
and close()
system calls are also needed. Given the descriptor yielded by inotify_init()
, call read()
to wait for alerts. Assuming a typical file descriptor, the application blocks pending the receipt of events, which are expressed as data in the stream. The common close() on the file descriptor yielded from inotify_init()
deletes and frees all active watches as well as all memory associated with the inotify instance. (The typical reference count caveat applies here, too. All file descriptors associated with an instance must be closed before the memory consumed by the watches and by inotify is freed.)
在read()
和close()
还需要系统调用。给定由 产生的描述符inotify_init()
,调用read()
等待警报。假设一个典型的文件描述符,应用程序阻塞等待事件的接收,这些事件在流中表示为数据。文件描述符上的公共 close()inotify_init()
删除并释放所有活动的监视以及与 inotify 实例关联的所有内存。(典型的引用计数警告也适用于此。与实例关联的所有文件描述符必须在手表和 inotify 消耗的内存被释放之前关闭。)
- An example ( from Kernel Korner - Intro to inotify)
- 一个例子(来自Kernel Korner - Intro to inotify)
#include "inotify.h" #include "inotify-syscalls.h" int wd; wd = inotify_add_watch (fd, "/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE); if (wd < 0) perror ("inotify_add_watch");
#include "inotify.h" #include "inotify-syscalls.h" int wd; wd = inotify_add_watch (fd, "/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE); if (wd < 0) perror ("inotify_add_watch");
This example adds a watch on the directory /home/rlove/Desktop for any modifications, file creations or file deletions.
此示例在目录 /home/rlove/Desktop 上添加了一个监视,用于任何修改、文件创建或文件删除。
回答by Fabian
Below is a snippet of how you can use inotify to watch "aaa". Note that I haven't tested this, I haven't even compiled it! You will need to add error checking to it.
下面是如何使用 inotify 观看“aaa”的片段。请注意,我还没有测试过这个,我什至没有编译它!您将需要为其添加错误检查。
Instead of using a blocking read you can also use poll/select on inotfd.
除了使用阻塞读取,您还可以在 inotfd 上使用 poll/select。
const char *filename = "aaa";
int inotfd = inotify_init();
int watch_desc = inotify_add_watch(inotfd, filename, IN_MODIFY);
size_t bufsiz = sizeof(struct inotify_event) + PATH_MAX + 1;
struct inotify_event* event = malloc(bufsiz);
/* wait for an event to occur */
read(inotfd, event, bufsiz);
/* process event struct here */
回答by user2567875
Since the initial question seems to mention Qt as a tag as noted in several comments here, search engines may have lead you here.
由于最初的问题似乎提到了 Qt 作为标签,如这里的几条评论中所述,搜索引擎可能会将您带到这里。
If somebody want to know how to do it with Qt, see http://doc.qt.io/qt-5/qfilesystemwatcher.htmlfor the Qt-version. On Linux it uses a subset of Inotify, if it is available, see explanation on the Qt page for details.
如果有人想知道如何使用 Qt,请参阅 Qt 版本的http://doc.qt.io/qt-5/qfilesystemwatcher.html。在 Linux 上,它使用 Inotify 的一个子集,如果可用,请参阅 Qt 页面上的说明以获取详细信息。
Basically the needed code looks like this:
基本上所需的代码如下所示:
in mainwindow.h add :
在 mainwindow.h 添加:
QFileSystemWatcher * watcher;
private slots:
void directoryChanged(const QString & path);
void fileChanged(const QString & path);
and for mainwindow.cpp:
对于 mainwindow.cpp:
#include <QFileInfo>
#include <QFileSystemWatcher>
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
watcher->addPath("/tmp/"); // watch directory
watcher->addPath("/tmp/a.file"); // watch file
also add the slots in mainwindow.cpp which are called if a file/directory-change is noticed:
还要在 mainwindow.cpp 中添加插槽,如果注意到文件/目录更改,则会调用这些插槽:
void MainWindow::directoryChanged(const QString & path) {
qDebug() << path;
}
void MainWindow::fileChanged(const QString & path) {
qDebug() << path;
}
回答by activedecay
If all you need is a commandline application, there is one called inotifywait
that watches files using inotify
如果你需要的只是一个命令行应用程序,那么有一个叫做inotifywait
监视文件的应用程序inotify
from terminal 1
从终端 1
# touch cheese
# while inotifywait -e modify cheese; do
> echo someone touched my cheese
> done
from terminal 2
从 2 号航站楼
echo lol >> cheese
here is what is seen on terminal 1
这是在终端 1 上看到的
Setting up watches.
Watches established.
cheese MODIFY
someone touched my cheese
Setting up watches.
Watches established.
Update: use with caution and see the comments.
更新:谨慎使用并查看评论。