2012-11-09 90 views
1

我的下面的示例代碼觀看被修改的文件。讓我們說被移動的文件是foo.txt,並且來自示例代碼的二進制名稱是inotify。我爲示例代碼做了兩個測試。inotify不把Vim編輯作爲修改事件

TEST1:
1)./inotify foo.txt的
2)回聲 「你好」> foo.txt的
然後一切正常,而 「文件改性」 已被打印出來。

TEST2:
1)./infity foo.txt的
2)VIM foo.txt的
3)編輯以某種方式和保存,但不退出VIM
印刷出來線是未知面膜0x00008000,簽出inotify頭文件發現此事件掩碼意味着IN_CLOSE_WRITE

從我的角度來看,「編輯和保存」只是menas修改。但是令人難以置信的是inotify代碼有一個不同的interpration它。這對我來說很奇怪,誰能幫助解釋背後的事情?

#include <sys/inotify.h> 
#include <stdio.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <stdlib.h> 


int main(int argc, char **argv) 
{ 
    int fdnotify = -1; 

    if (argc !=2) { 
    fprintf(stderr, "usage: ./inotify dir_name\n"); 
    exit(1); 
    } 

    printf("argc is %d\n", argc); 

    fdnotify = inotify_init(); 
    if (fdnotify < 0) { 
    fprintf(stderr, "inotity_init failed: %s\n", strerror(errno)); 
    } 

    int wd = inotify_add_watch(fdnotify, argv[1], IN_MODIFY); 
    if (wd < 0) { 
    fprintf(stderr, "inotify_add_watch failed: %s\n", strerror(errno)); 
    } 

    while(1) { 
    char buffer[4096]; 
    struct inotify_event *event = NULL; 

    int len = read(fdnotify, buffer, sizeof(buffer)); 

    if (len < 0) { 
     fprintf(stderr, "read error %s\n", strerror(errno)); 
    } 

    event = (struct inotify_event *) buffer; 

    while(event != NULL) { 
     if ((event->mask & IN_MODIFY) ) { 
     printf("File modified %s\n", event->name); 
     } else { 
printf("unknown Mask 0x%.8x\n", event->mask); 
     } 
     len -= sizeof(*event) + event->len; 

     if (len > 0) 
     event = ((void *) event) + sizeof(event) + event->len; 
     else 
     event = NULL; 
    } 
    } 
} 
+0

什麼'inotifywait -m foo.txt'不得不說關於正在生成的事件? – arcticmac

回答

5

Vim是一個在保存文件時不直接保存到文件的程序。它創建一個通常名爲.filename.swp的臨時文件,並且只有當您關閉vim時,該文件纔會重命名爲filename。從inotify的的FAQ:

的IN_MODIFY事件被髮射上的文件內容的變更(例如,經由寫()系統調用)而IN_CLOSE_WRITE上關閉改變的文件發生。這意味着每個更改操作都會導致一個IN_MODIFY事件(在打開文件的操作過程中可能會出現多次),而IN_CLOSE_WRITE只發出一次(關閉文件時)。

所以你得到的事件實際上是有道理的。假設你有一個名爲filename的文件。當您打開文件filename時,會創建名爲.filename.swp的另一個文件。如果對此文件執行的所有修改都將受到監視,則會生成一些事件IN_MODIFY。當你實際保存時,最終發生的事情是,vim重命名這個文件並關閉它,從而生成IN_CLOSE_WRITE事件。

+0

請注意,OP說他在vim仍在運行時說'IN_CLOSE_WRITE'。嘗試打開文件,保存並保持vim打開。如果你抓住這個文件,你會看到你的改變。 –

+0

vim的交換文件格式不僅僅是正在編輯的文件的文本副本。嘗試'交換文件'貓,你會得到一堆二進制垃圾,加上文件的一些內容(似乎新行缺失?)。我認爲每次完成一個命令vim都會更新交換文件,但它至少在我的測試案例中直接修改了原始文件。 – arcticmac

1

我以爲面膜0x00008000被IN_IGNORED 根據inotify.h:

#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed. */ 
#define IN_IGNORED 0x00008000 /* File was ignored. */ 

它是更多鈔票的事件掩碼是IN_IGNORED?