inotify监控文件夹
参考方案
https://docs.rockylinux.org/zh/books/learning_rsync/06_rsync_inotify/
引子
由于项目要求,需要使用定时任务采集某个目录下的文件进行解析;
需求很简单,实现起来也不复杂:我们只需要根据文件的创建时间(或者文件的最后修改时间) 和定时任务上一次的执行时间作对比,如果发现文件创建时间(或者文件的最后修改时间)大于上一次执行的时间,说明文件需要解析,否则则忽略;
但是实现的时候发现了一个问题: 由于文件的创建时间或者最后修改时间作为文件的元数据在文件中进行存储,复制或者移动该文件时这个元数据并不会发生变化;
所以就会出现一种情况:文件是2024年7月1号创建的,但是该文件并没有立刻放入到该采集文件中,假设:定时任务在7月12号 18点执行完毕后,用户将这个文件放入到采集文件夹,在用户看来这个文件应该被采集,但实际上这个文件的创建时间却是:7月1日,实际上并不会被采集。
这篇文件就是用来解决这个问题的。
一、实现思路
由于采集文件夹是放在 SMB 共享盘中的,所以归拢了一下解决方案如下:
- SMB服务中添加配置,放入SMB共享盘的文件自动修改最后更新时间为当前时间 (上策)
- 监控采集文件夹,所有针对于创建或者移动的事件监听,然后将该文件的最后修改时间设置为当前时间 (下策)
1.1、方案一
网上搜索了一大圈,发现 SMB 并没有提供对应的操作方式,所以这种最优的方案就被扼杀在摇篮中了;
1.2、方案二
由于服务器是使用的 centos,这种监听文件的方案还是很多的,例如:
auditd
、fswatch
、inotify
还有 Systemd 文件单元
;
经过了解发现:Systemd 文件单元
只能够发现文件被操作了,但是不能够获取到 具体是那个文件,这不是鸡肋嘛,直接pass;
最终选择了方案比较成熟的:inotify
。
二、inotifywait的实现
inotifywait
是一个用于监控文件系统事件的命令行工具,它基于 Linux 内核的 inotify 机制。
inotifywait
命令可以实时监控文件或目录的事件,例如文件的创建、删除、修改等,并在事件发生时执行指定的操作。
2.1、inotify-tools详解
inotify-tools工具有两个命令,分别是:
inotifywait:用于持续监控,实时输出结果。 它通常与 rsync 增量备份工具一起使用。 因为它是对文件系统的监控,所以可以搭配脚本一起使用。
inotifywatch:用于短期监控,任务完成后输出结果。
inotifywait 主要有以下选项:
- -m 表示持续监控
- -r 递归监控
- -q 简化输出信息
- -e 指定监控数据的事件类型,多个事件类型用英文状态的逗号隔开
事件类型如下:
事件类型 | 说明 |
---|---|
access | 文件或目录的内容进行访问 |
modify | 文件或目录的内容被写入 |
attrib | 文件或目录的属性被修改 |
close_write | 文件或目录在可写模式下打开后关闭 |
close_nowrite | 文件或目录在以只读模式打开后关闭 |
close | 无论读/写模式,文件或目录关闭 |
open | 文件或者目录被打开 |
moved_to | 有文件或目录移动到监控的目录中 |
moved_from | 有文件或目录从监控的目录中移出 |
move | 有文件或者目录,被移动到监控目录或者从监控目录中移出 |
move_self | 已移动受监视的文件或目录 |
create | 被监控的目录内有创建的文件或目录 |
delete | 被监控的目录内有文件或目录被删除 |