inotify 在 Linux 上的应用

320 阅读3分钟

介绍 inotify 在 Linux 上的应用

什么是 inotify

inotify(inode notify)是 Linux 内核提供的一种文件系统监控机制,它允许程序高效地监控文件系统中的事件,例如文件的创建、删除、修改等。与传统的轮询方法相比,inotify 提供了一种高效的方式来检测文件系统变化,极大地减少了系统资源的消耗。

inotify 的工作原理

inotify 通过内核 API 实现,应用程序可以使用这个 API 来监控特定文件或目录的变化。它通过文件描述符和事件掩码(mask)来指定需要监控的文件和需要监控的事件。内核在检测到相应事件时,会通过文件描述符将事件通知应用程序。

inotify 的用途

inotify 广泛应用于各种需要实时文件系统监控的场景,包括但不限于:

  1. 文件同步:实时检测文件变化以进行同步操作,如 Dropbox、rsync 等工具。
  2. 日志监控:实时监控日志文件的变化,便于日志分析和管理。
  3. 安全监控:检测和记录文件系统中的异常活动,提供安全审计。
  4. 自动化工具:自动执行脚本或程序,例如自动化编译系统中的文件变化检测。

使用 inotify 的基本步骤

  1. 初始化 inotify 实例

    int inotify_fd = inotify_init();
    if (inotify_fd < 0) {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }
    
  2. 添加监控项

    int watch_descriptor = inotify_add_watch(inotify_fd, "/path/to/directory_or_file", IN_MODIFY | IN_CREATE | IN_DELETE);
    if (watch_descriptor < 0) {
        perror("inotify_add_watch");
        close(inotify_fd);
        exit(EXIT_FAILURE);
    }
    
  3. 读取事件

    char buffer[1024];
    ssize_t length = read(inotify_fd, buffer, sizeof(buffer));
    if (length < 0) {
        perror("read");
        close(inotify_fd);
        exit(EXIT_FAILURE);
    }
    
    struct inotify_event *event;
    for (char *ptr = buffer; ptr < buffer + length; ptr += sizeof(struct inotify_event) + event->len) {
        event = (struct inotify_event *) ptr;
        if (event->mask & IN_CREATE) {
            printf("File %s created.\n", event->name);
        } else if (event->mask & IN_DELETE) {
            printf("File %s deleted.\n", event->name);
        } else if (event->mask & IN_MODIFY) {
            printf("File %s modified.\n", event->name);
        }
    }
    

常用的 inotify 事件标志

  • 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:被监控的文件或目录自身被移动

示例程序

以下是一个使用 inotify 监控 /tmp 目录中文件变化的简单示例程序:

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

int main() {
    int inotify_fd = inotify_init();
    if (inotify_fd < 0) {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }

    int watch_descriptor = inotify_add_watch(inotify_fd, "/tmp", IN_CREATE | IN_DELETE | IN_MODIFY);
    if (watch_descriptor < 0) {
        perror("inotify_add_watch");
        close(inotify_fd);
        exit(EXIT_FAILURE);
    }

    char buffer[1024];
    while (1) {
        ssize_t length = read(inotify_fd, buffer, sizeof(buffer));
        if (length < 0) {
            perror("read");
            break;
        }

        struct inotify_event *event;
        for (char *ptr = buffer; ptr < buffer + length; ptr += sizeof(struct inotify_event) + event->len) {
            event = (struct inotify_event *) ptr;
            if (event->mask & IN_CREATE) {
                printf("File %s created.\n", event->name);
            } else if (event->mask & IN_DELETE) {
                printf("File %s deleted.\n", event->name);
            } else if (event->mask & IN_MODIFY) {
                printf("File %s modified.\n", event->name);
            }
        }
    }

    close(watch_descriptor);
    close(inotify_fd);
    return 0;
}

这个程序会持续监控 /tmp 目录,并在文件被创建、删除或修改时打印相应的消息。

总结

inotify 是一个强大而高效的文件系统监控工具,广泛应用于需要实时监控文件变化的场景中。通过 inotify 提供的 API,开发者可以轻松实现各种文件系统监控任务,提高系统的自动化和响应能力。