4.4 使用pyinotify监控文件系统变化

4.4.1 pyinotify模块介绍

pyinotify模块用来监测文件系统的变化,依赖于Linux内核的inotify功能,inotify是一个事件驱动的通知器,其通知接口从内核空间到用户空间通过三个系统调用。pyinotify结合这些系统调用,提供一个顶级的抽象和一个通用的方式来处理这些功能。

4.4.2 pyinotify模块API

使用如下命令安装pyinotify模块:

pip install pyinotify

Notifier是pyinotify模块最重要的类,用来读取通知和处理事件,默认情况下,Notifier处理事件的方式是打印事件。

Notifier类在初始化时接受多个参数,但是只有WatchManager对象是必须传递的参数,WatchManager对象保存了需要监视的文件和目录,以及监视文件和目录的哪些事件,Notifier类根据WatchManager对象中的配置来决定如何处理事件。

#!/usr/bin/python3
import pyinotify

wm = pyinotify.WatchManager()              # 创建WatchManager对象
wm.add_watch('/tmp',pyinotify.ALL_EVENTS)  # 添加要监控的目录,以及要监控的事件,这里ALL_EVENT表示所有事件

notifier = pyinotify.Notifier(wm)          # 交给Notifier进行处理
notifier.loop()                            # 循环处理事件

运行结果为:

root@liu-ubuntu:~# ./17-pyinotify.py 
<Event dir=True mask=0x40000100 maskname=IN_CREATE|IN_ISDIR name=abc path=/tmp pathname=/tmp/abc wd=1 >
<Event dir=True mask=0x40000020 maskname=IN_OPEN|IN_ISDIR name=abc path=/tmp pathname=/tmp/abc wd=1 >
<Event dir=True mask=0x40000001 maskname=IN_ACCESS|IN_ISDIR name=abc path=/tmp pathname=/tmp/abc wd=1 >
<Event dir=True mask=0x40000010 maskname=IN_CLOSE_NOWRITE|IN_ISDIR name=abc path=/tmp pathname=/tmp/abc wd=1 >
<Event dir=True mask=0x40000200 maskname=IN_DELETE|IN_ISDIR name=abc path=/tmp pathname=/tmp/abc wd=1 >

其中第1行是在另一个终端中执行了:

mkdir abc

第2-5行是在另一个终端中执行了:

rm -r abc

4.4.3 事件标志与事件处理器

pyinotify 仅仅是对 inotify 的Python封装,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_CLOSE* 文件被关闭,等同于IN_CLOSE_WRITE*
IN_MOVE 文件被移动,等同于IN_CLOSE_NOWRITE

上面列举的是事件的标志位,我们可以用'与'来关联监控多个事件。

multi_event = pyinotify.IN_OPEN | pyinotify.IN_CLOSE_NOWRITE