c使用inotify監(jiān)控linux路徑下文件變化

  1. 簡(jiǎn)介:

Inotify 是一個(gè) Linux 內(nèi)核特性,它監(jiān)控文件系統(tǒng),并且及時(shí)向?qū)iT的應(yīng)用程序發(fā)出相關(guān)的事件警告,比如刪除、讀、寫和卸載操作等。您還可以跟蹤活動(dòng)的源頭和目標(biāo)等細(xì)節(jié)。

使用 inotify 很簡(jiǎn)單:創(chuàng)建一個(gè)文件描述符,附加一個(gè)或多個(gè)監(jiān)視器(一個(gè)監(jiān)視器 是一個(gè)路徑和一組事件),然后使用 read() 方法從描述符獲取事件信息。read() 并不會(huì)用光整個(gè)周期,它在事件發(fā)生之前是被阻塞的。

更好的是,因?yàn)?inotify 通過(guò)傳統(tǒng)的文件描述符工作,您可以利用傳統(tǒng)的 select() 系統(tǒng)調(diào)用來(lái)被動(dòng)地監(jiān)控監(jiān)視器和許多其他輸入源。兩種方法 — 阻塞文件描述符和使用 select()— 都避免了繁忙輪詢。

要使用 inotify,您必須具備一臺(tái)帶有 2.6.13 或更新內(nèi)核的 Linux 機(jī)器(以前的 Linux 內(nèi)核版本使用更低級(jí)的文件監(jiān)控器 dnotify)。如果您不知道內(nèi)核的版本,請(qǐng)轉(zhuǎn)到 shell,輸入 uname -a

  1. 首先看一下inotify.h中定義的watch mask:
IN_ACCESS
The file was read from.

IN_MODIFY
The file was written to.

IN_ATTRIB
The file’s metadata (for example, the owner, permissions, or extended attributes) was changed.

IN_CLOSE_WRITE
The file was closed and had been open for writing.

IN_CLOSE_NOWRITE
The file was closed and had not been open for writing.

IN_OPEN
The file was opened.

IN_MOVED_FROM
A file was moved away from the watched directory.

IN_MOVED_TO
A file was moved into the watched directory.

IN_CREATE
A file was created in the watched directory.

IN_DELETE
A file was deleted from the watched directory.

IN_DELETE_SELF
The watched object itself was deleted.

IN_MOVE_SELF
The watched object itself was moved.

The following events are also defined, grouping two or more events into a single value:

IN_ALL_EVENTS
All legal events.

IN_CLOSE
All events related to closing (currently, both IN_CLOSE_WRITE and IN_CLOSE_NOWRITE).

IN_MOVE

All move-related events (currently, both IN_MOVED_FROM and IN_MOVED_TO).

有了以上的watch mask就可以從終端的輸出清晰的得知文件進(jìn)行了什么樣的操作。

2. 上代碼:

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <sys/inotify.h>  
#include <unistd.h>  
 
#define EVENT_NUM 12  
 
char *event_str[EVENT_NUM] =
{
    "IN_ACCESS",
    "IN_MODIFY",
    "IN_ATTRIB",
    "IN_CLOSE_WRITE",
    "IN_CLOSE_NOWRITE",
    "IN_OPEN",
    "IN_MOVED_FROM",
    "IN_MOVED_TO",
    "IN_CREATE",
    "IN_DELETE",
    "IN_DELETE_SELF",
    "IN_MOVE_SELF"
};
 
int main(int argc, char *argv[])
{
    int fd;
    int wd;
    int len;
    int nread;
    char buf[BUFSIZ];
    struct inotify_event *event;
    int i;
 
    if (argc < 2)
    {
        fprintf(stderr, "%s path\n", argv[0]);
        return -1;
    }
 
    fd = inotify_init();
    if (fd < 0)
    {
        fprintf(stderr, "inotify_init failed\n");
        return -1;
    }
 
    wd = inotify_add_watch(fd, argv[1], IN_ALL_EVENTS);
    if (wd < 0)
    {
        fprintf(stderr, "inotify_add_watch %s failed\n", argv[1]);
        return -1;
    }
 
    buf[sizeof(buf) - 1] = 0;
    while ((len = read(fd, buf, sizeof(buf) - 1)) > 0)
    {
        nread = 0;
        while (len > 0)
        {
            event = (struct inotify_event *)&buf[nread];
            for (i = 0; i<EVENT_NUM; i++)
            {
                if ((event->mask >> i) & 1)
                {
                    if (event->len > 0)
                        fprintf(stdout, "%s --- %s\n", event->name, event_str[i]);
                    else
                        fprintf(stdout, "%s --- %s\n", " ", event_str[i]);
                }
            }
            nread = nread + sizeof(struct inotify_event) + event->len;
            len = len - sizeof(struct inotify_event) - event->len;
        }
    }
 
    return 0;
}

然后新建inotify.c文件,將代碼粘貼進(jìn)去中,終端使用如下命令編譯測(cè)試:

gcc inotify.c -o ity

終端運(yùn)行可執(zhí)行文件ity:

./ity  ./   (后面需要加上監(jiān)聽路徑,此處是監(jiān)聽當(dāng)前文件)

效果:
[root@iZbp1e0ge3ve4pv3k7gzkeZ htdocs]# ./ity ./
ity --- IN_OPEN
ity --- IN_ACCESS
ity --- IN_CLOSE_NOWRITE
ity --- IN_OPEN
ity --- IN_CLOSE_NOWRITE
ity --- IN_OPEN
ity --- IN_CLOSE_NOWRITE
ity --- IN_OPEN
ity --- IN_ACCESS
ity --- IN_CLOSE_NOWRITE
ity --- IN_OPEN
ity --- IN_ACCESS
ity --- IN_CLOSE_NOWRITE
  --- IN_OPEN
  --- IN_CLOSE_NOWRITE
a.txt --- IN_DELETE
index.html --- IN_OPEN
index.html --- IN_ACCESS
index.html --- IN_CLOSE_NOWRITE

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容