Inotify vim修改

时间:2012-11-16 03:14:40

标签: inotify

我正在尝试使用inotify来监视文件以便在无限循环中进行修改。我遇到了一些问题:

1)我有一段时间(1),并且读取不起作用,除非我为while的每次迭代创建一个新的文件描述符和一个新的监视描述符(我想要做的是打开那些描述符之前无限循环,但如果其他解决方案是可接受的,那么我可以使用它)。这是有效的版本:

 while(1){
    int file_descriptor = inotify_init();
    if (file_descriptor < 0) {
        perror("inotify_init");
    }

    int watch_descriptor = inotify_add_watch(file_descriptor, "/home/user/hello.cfg", IN_CLOSE_WRITE);
    ....

2)我尝试使用掩码IN_MODIFY,但我读到它与vim不兼容,所以我使用IN_CLOSE_WRITE。问题是当我用vim修改文件时,会读取事件,但事件的掩码是IN_IGNORED(掩码0x00008000)。当我使用gedit时,有时事件的掩码是IN_IGNORED,有时是IN_CLOSE_WRITE(掩码0x0000008)。我想知道为什么我得到IN_IGNORED如果我正在修改文件,以及为什么事件不是IN_CLOSE_WRITE。还有另一种方法可以监视单个文件的修改吗? IN_CLOSE_WRITE是正确的掩码吗?

1 个答案:

答案 0 :(得分:1)

我在编写一个守护进程时发现了相同的行为(内核3.14.4),该守护进程在运行时更改后会自动重新加载其配置文件。我发现一些程序(其中的vim)导致inotify生成IN_IGNORED,因为它们删除了原始文件并将其替换为&#34; swap&#34;文件。

来自inotify文档,

       IN_IGNORED
              Watch was removed explicitly (inotify_rm_watch(2)) or
              automatically (file was deleted, or filesystem was
              unmounted).  See also BUGS.

你可以通过运行

来看到这一点
strace -o log vi myfile.txt

并检查日志中的strace结果,该结果将显示.myfile.txt.swp的创建和删除。

解决方案是捕获IN_IGNORED事件并为您的文件重新添加监视,即

int watch_descriptor = inotify_add_watch(file_descriptor, "/home/user/hello.cfg", (IN_CLOSE_WRITE | IN_IGNORED));

IN_CLOSE_WRITE是要处理的正确事件,但也有一个问题。有些程序会打开一个文件进行读写,但只能从中读取。当他们关闭文件时,即使文件未被修改,也会生成IN_CLOSE_WRITE。

我发现最好的方法是为我正在观看的每个文件保留一个标志,并在我捕获IN_MODIFY时切换它。然后,当生成IN_CLOSE_WRITE时,可以检查该标志以确定IN_CLOSE_WRITE是否有意义。