使用Inotify监控文件及文件夹

最近写一些shell脚本的时候,需要读取远程服务器的目录下的文件同步到当前服务器的指定目录下,因为使用的是增量同步,所以需要监控文件夹下文件的变化,最终选择使用Inotify用来监控。

Inotify是一种文件变化通知机制,Linux内核从2.6.13开始引入,它可以高效的跟踪Linux文件系统的变化。

一、判断内核支持Inotify

grep "CONFIG_INOTIFY_USER" /boot/config-$(uname -r)

命令执行后如下:

如果输出内容中包含CONFIG_INOTIFY_USER=y说明操作系统支持Inotify

二、安装inotify-tools

下载与解压缩

wget https://nchc.dl.sourceforge.net/project/inotify-tools/inotify-tools/3.13/inotify-tools-3.13.tar.gz
tar zxvf inotify-tools-3.13.tar.gz

配置

cd inotify-tools-3.13
./configure --prefix=/usr/local/inotify-tools-3.13

编译安装

make && make install

配置环境变量

# 删除INOTIFY_TOOLS_HOME配置
sed -i '/INOTIFY_TOOLS_HOME/d' /etc/profile
# 添加INOTIFY_TOOLS_HOME环境变量
echo 'export INOTIFY_TOOLS_HOME=/usr/local/inotify-tools-3.13/' >> /etc/profile
# 添加inotify tools的可执行文件到PATH环境变量
echo 'export PATH=$PATH:$INOTIFY_TOOLS_HOME/bin' >> /etc/profile
# 使环境变量生效
source /etc/profile

三、inotifywait

此命令可以用于监控文件及文件夹,可以使用man inotifywait查看命令的帮助文档

1、监听

下面我们使用inotifywait监控/home文件夹下文件的变化,执行命令:

# m代表的是循环监听,否则监听到后退出
# r代表的是递归监听,否则只监听指定文件夹下的变化
inotifywait -rm /home

执行命令后,会一直处于阻塞状态:

打开另外一个终端,依次在/home/dev目录下完成以下操作:

  1. 新建一个文件夹(mkdir test)
  2. 进入test文件夹,创建text.txt文件(cd test && touch text.txt)
  3. 修改text.txt文件的内容(echo 'hello world'>> text.txt)
  4. 查看text.txt文件的内容(more text.txt)
  5. 删除text.txt文件(rm text.txt)
  6. 进入/home/dev目录,删除test目录(rm -r test)

可以看到监听到的日志如下:

可以看到inotifywait监听到的事件,大体上还是很清晰的。如果想了解inotify提供的事件,可以参考:https://linux.die.net/man/1/inotifywatch

2、排除监听

在某些情况下我们可能不想监听某个文件或文件夹的变化,我们可以使用--exclude排除对指定文件或文件夹的监听。

下面我们使用inotifywait监控/home文件夹下文件的变化,但不监听/home/dev下的变化,执行命令:

# m代表的是循环监听,否则监听到后退出
# r代表的是递归监听,否则只监听指定文件夹下的变化
inotifywait --exclude /home/dev -rm /home

再在/home/dev目录下执行创建文件及文件夹等操作,发现已经监听不到。

另外--exclude后面可以使用正则表达式

四、Inotify配置

内核中有两项关于Inotify的配置:

/proc/sys/fs/inotify/max_user_instances规定了每个用户所能创建的 Inotify 实例的上限(默认是128)

/proc/sys/fs/inotify/max_user_watches规定了每个Inotify实例最多能关联几个监控 (watch)(默认是8192)

1、修改用户Inotify实例上限

下面我们将max_user_instances修改为0:

echo 0 > /proc/sys/fs/inotify/max_user_instances

再使用inotifywait命令进行监听时会失败:

测试结束后将max_user_instances再修改回128

2、修改Inotify关联watch上限

下面我们将max_user_watches修改为0:

echo 0 > /proc/sys/fs/inotify/max_user_watches

再使用inotifywait命令进行监听时会失败:

测试结束后将max_user_watches再修改回8192

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 epoll 和 inotify 监控文件,需要进行以下步骤: 1. 创建一个 epoll 实例并将其添加到监听文件描述符列表中。 2. 创建一个 inotify 实例并将其添加到 epoll 实例中。 3. 使用 inotify_add_watch 函数添加要监视的文件或目录。 4. 启动 epoll 循环,并等待事件发生。 5. 当有事件发生时,使用 epoll_wait 函数获取事件列表。 6. 遍历事件列表,处理每个事件。如果是 inotify 事件,则读取事件并处理它。 7. 如果需要继续监视文件,则重复步骤 4-6。 下面是一个简单的示例代码,用于监视目录中的文件创建或删除事件: ```c #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <sys/inotify.h> #define MAX_EVENTS 10 #define EVENT_SIZE (sizeof (struct inotify_event)) #define BUF_LEN (MAX_EVENTS * (EVENT_SIZE + 16)) int main(int argc, char const *argv[]) { int fd, wd, epfd, n, i; char buf[BUF_LEN]; struct epoll_event event; struct epoll_event events[MAX_EVENTS]; // create an inotify instance fd = inotify_init(); if (fd < 0) { perror("inotify_init"); exit(EXIT_FAILURE); } // add the inotify instance to epoll epfd = epoll_create(1); if (epfd < 0) { perror("epoll_create"); exit(EXIT_FAILURE); } event.data.fd = fd; event.events = EPOLLIN | EPOLLET; if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event) < 0) { perror("epoll_ctl"); exit(EXIT_FAILURE); } // add directory to watch list wd = inotify_add_watch(fd, "/path/to/directory", IN_CREATE | IN_DELETE); if (wd < 0) { perror("inotify_add_watch"); exit(EXIT_FAILURE); } while (1) { // wait for events n = epoll_wait(epfd, events, MAX_EVENTS, -1); if (n < 0) { perror("epoll_wait"); break; } for (i = 0; i < n; i++) { if (events[i].data.fd == fd) { // read inotify events int len = read(fd, buf, BUF_LEN); if (len < 0) { perror("read"); break; } char *p = buf; while (p < buf + len) { struct inotify_event *event = (struct inotify_event *) p; printf("event: %s\n", event->name); p += sizeof(struct inotify_event) + event->len; } } } } // cleanup inotify_rm_watch(fd, wd); close(fd); close(epfd); return 0; } ``` 在此示例中,我们创建了一个 inotify 实例并将其添加到 epoll 实例中。然后,我们使用 inotify_add_watch 函数添加要监视的目录,并指定要监视的事件类型(在本例中为文件创建和删除事件)。最后,我们启动 epoll 循环,并等待事件发生。当事件发生时,我们读取 inotify 事件并处理它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值