【问题标题】:`inotify` notifies only the first change in a file`inotify` 仅通知文件中的第一次更改
【发布时间】:2021-09-24 09:31:54
【问题描述】:

我想编写一个简单的 C 程序来检测常规文件中的更改。我决定使用inotify。问题是我的程序只检测到文件中的第一次更改。 这是我的代码:

#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>

#define EVENT_SIZE  (sizeof(struct inotify_event))
#define BUF_LEN     (1024*(EVENT_SIZE + 16))


int main()
{
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

    fd = inotify_init();

    if (fd < 0) {
        perror("inotify_init");
    }

    wd = inotify_add_watch(fd, "/path/to/my/file.txt", IN_MODIFY);

    while(1)
    {
        length = read(fd, buffer, BUF_LEN);
        if (length < 0) {
            perror("read");
        }  
        
        while (i < length) {
            struct inotify_event* event = (struct inotify_event*) &buffer[i];
            if (event->len) {
                if (event->mask & IN_MODIFY) {
                        printf("The file %s was modified.\n", event->name);
                }
            }
            i += EVENT_SIZE + event->len;
        }
    }
    inotify_rm_watch(fd, wd);
    close(fd);

    return 0;
}

read() 返回 0,所以我的程序永远不会从 while(i&lt;length){} 退出。当我注释掉这个循环时,read() 似乎只在文件中的第一次更改时返回任何值,然后它会永远等待。

您知道为什么我无法检测到文件中的更改吗?提前感谢您的帮助。

编辑我检查了 inotify 的 cli 版本,它也没有按预期工作。我打电话给inotifywait -m file.txt,它说我的文件已被删除,但我所做的唯一更改是添加一些字母并保存。这是命令的完整输出:

Setting up watches.
Watches established.
file.txt OPEN 
file.txt CLOSE_WRITE,CLOSE 
file.txt ATTRIB 
file.txt DELETE_SELF 

【问题讨论】:

  • 我的文件已被删除,但我所做的唯一更改是添加一些字母并保存。你怎么知道你的编辑没有删除文件?
  • 我还有磁盘上的文件,可以打开和编辑。
  • 你有什么证据表明它是 same 文件?
  • 同名,同一个位置。难道每次保存后这个文件都会被删除?这对我来说很奇怪。那我应该怎么做才能使用inotify
  • 对文件运行ls -i(小写字母“i”)并查看inode编号是否更改。请注意,如果 inode 编号保持不变,这并不意味着您的编辑器没有删除该文件 - 它只是意味着具有相同名称的新文件可能已收到相同的 inode 编号。如果发生这种情况,您必须在目录上放置一个 inotify 监视并监视文件创建并跟踪它们。但这取决于比赛条件,并且会错过比赛。

标签: linux file inotify


【解决方案1】:

首先,您没有在循环内重置i,因此第一次将其增加到EVENT_SIZE,后续长度为EVENT_SIZE 的读取将不会被查看。

此外,您正在检查文件名的长度 event-&gt;len 是否非零,但至少手册页上说:

名称字段仅在为监视目录中的文件返回事件时出现;它标识了被监视目录中的文件名。

所以当您只观看单个文件时它不会被填充。

如果你修复它重置i;并查看整个目录,或者不看event-&gt;name,那么它可以工作。

【讨论】:

  • 感谢您指出错误。我已经纠正了他们。但是,我仍然遇到文件第一次更改后,程序停在read() 的问题。出于好奇,我检查了 inotify 的控制台版本是如何工作的,我打电话给inotifywait -m file.txt,结果发现它也没有按预期工作。我将控制台结果添加到问题中。
  • @userr019283,好吧,您使用inotifywait 运行表明该文件没有被修改,而是被删除。可能被另一个在顶部重命名的文件所取代。有你的问题。
猜你喜欢
  • 1970-01-01
  • 2012-08-27
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多