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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:48:00  来源:igfitidea点击:

What is the proper way to use inotify?

linuxinotify

提问by dubila

I want to use the inotifymechanism on Linux. I want my application to know when a file aaawas changed. Can you please provide me with a sample how to do that?

我想inotify在 Linux 上使用该机制。我希望我的应用程序知道文件何时aaa更改。你能给我提供一个如何做到这一点的样本吗?

采纳答案by joschi

The inotifyC API

inotifyC API

inotifyprovides three system calls to build file system monitors of all kinds:

inotify提供三个系统调用来构建各种文件系统监视器:

  • inotify_init()creates an instance of the inotifysubsystem in the kernel and returns a file descriptor on success and -1on failure. Like other system calls, if inotify_init()fails, check errnofor 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 as IN_MODIFY. To monitor more than one event, simply use the logical or — the pipe (|) operator in C—between each event. If inotify_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 消耗的内存被释放之前关闭。)

#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 inotifywaitthat 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.

更新:谨慎使用并查看评论。