Linux文件监控方法

Linux系统开发程序,有时候需要监控配置文件的变化,做出相应操作,下面将介绍常用的文件、目录监控方法:

函数介绍:

1.Inotify系列函数:

Inotify_init(void)

系统返回一个文件描述符,使用完毕需要释放(close)

2.Inotify_add_watch(int fd, const char *pathname, unsigned int mask)

添加对指定文件的监控,可以选择需要监控的事件(设置mask);

3.Inotify_rm_watch(int fd, unsigned int wd)

从fd指定的inotify实例中,删除wd指定的监控项

那么inotify事件有哪些?

1.常见的事件如下:

IN_ACCESS:文件被访问(read)

IN_ATTRIB:文件元数据改变

IN_CLOSE_WRITE:关闭为了写入而打开的文件

一般我们可以使用read从fd中读取事件,当无事件发生,则read会阻塞等待,当有事件发生,则返回inotify_event结构:

Struct inotify_event{

Int wd;

Unsigned int mask

Unsigned int cookie;

Unsigned int len;

Char name[];

};

下面用一个简单的示例演示循环监控文件变化:

复制代码
int ret = 0;
char buffer[MAX_BUFF] = {0};
int fd = inotify_init();

if(fd < 0){
    perror("init inotify failed.");
    return;
}

int wd = inotify_add_watch(fd, "/home/test.txt", IN_MODIFY | IN_CLOSE_WRITE | IN_IGNORED | IN_ATTRIB);//这里加了两个事件,稍后介绍

if(wd < 0){
    printf("cannot add watch for test.txt.\n");
    close(fd);//释放
    return;
}

fd_set rfds;
while(1){
    FD_ZERO(&rfds);
    FD_SET(fd, &rfds);
    ret = select(fd+1, &rfds, NULL, NULL, NULL);//监控read
    if(ret <= 0){//如果设置超时,可以做一些其他事情
        continue;
    }
    
    //event happened, so something
    bzero(buffer, sizeof(buffer));
    bet = (0 | read(fd, buffer, MAX_BUFF));
    if(ret < 0){
        printf("read inotify failed.");
        break;
    }

    int index = 0;
    while(index < ret){
        struct inotify_event *pevent = (struct inotify_event*)&buffer[index];
        unsigned int event_size = offsetof(struct inotify_event, name) + pevent->len;
        index += (0 | event_size);
        printf("event[wd:%d,mask:%u,cookie:%u,len:%u].", pevent->wd, pevent->mask, pevent->cookie, pevent->len);
        if(pevent->mask & IN_MODIFY){
           //do something
        }

        if(pevent->mask & IN_CLOSE_WRITE){
            //do something
        }

        if((pevent->mask & IN_IGNORED) || (pevent->mask & IN_ATTRIB)){
       //当触发IN_IGNORED或IN_ATTRIB事件时,需要重新调用inotify_add_watch,否则就只能检测一次,比如我们vi或mv文件时就会出现此种情况
            wd = inotify_add_watch(fd, "/home/test.txt", IN_MODIFY | IN_CLOSE_WRITE | IN_IGNORED | IN_ATTRIB );
        }
    }//end while index
}//end while 1

inotify_rm_watch(fd,wd);
close(fd);

参考文档:https://blog.flowlore.com/passages/inotify-shi-yong-jiao-cheng/

相关推荐
-To be number.wan4 小时前
C++ 赋值运算符重载:深拷贝 vs 浅拷贝的生死线!
前端·c++
张火火isgudi4 小时前
fedora43 安装 nvidia 驱动以及开启视频编解码硬件加速
linux·运维·视频编解码·nvidia
IT19955 小时前
Qt笔记-使用SSH2进行远程连接linux服务器并上传文件
linux·服务器·笔记
XXYBMOOO5 小时前
内核驱动开发与用户级驱动开发:深度对比与应用场景解析
linux·c++·驱动开发·嵌入式硬件·fpga开发·硬件工程
lengjingzju7 小时前
一网打尽Linux IPC(三):System V IPC
linux·服务器·c语言
大聪明-PLUS7 小时前
如何编写你的第一个 Linux 内核模块
linux·嵌入式·arm·smarc
知识分享小能手7 小时前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04文件压缩与解压缩知识点详解(12)
linux·学习·ubuntu
用户6135411460168 小时前
Krb5-libs-1.18.2-5.ky10.x86_64.rpm 安装失败怎么办?附详细步骤
linux
SoveTingღ9 小时前
【问题解析】我的客户端与服务器交互无响应了?
服务器·c++·qt·tcp
zhougl9969 小时前
Vuex 模块命名冲突:问题解析与完整解决方案
linux·服务器·apache