pyinotify介紹
pyinotify模塊用來監測文件系統的變化,依賴於Linux內核的inotify功能,inotify是一個事件驅動的通知器,其通知接口從內核空間到用戶空間通過三個系統調用。pyinotify結合這些系統調用,提供一個頂級的抽象和一個通用的方式來處理這些功能。
Linux在2.6.13版本以后才提供了inotify。
安裝pyinotify
這里使用如下命令安裝pyinotify模塊
pip3 install pyinotify
安裝完畢后,可以直接在命令行中使用
python3 -m pyinotify /tmp
當/tmp目錄發生事件時,會輸出事件信息
<Event dir=False mask=0x20 maskname=IN_OPEN name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x1 maskname=IN_ACCESS name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x10 maskname=IN_CLOSE_NOWRITE name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x2 maskname=IN_MODIFY name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x20 maskname=IN_OPEN name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x2 maskname=IN_MODIFY name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 > <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=daxin.txt path=/tmp pathname=/tmp/daxin.txt wd=1 >
pyinotify模塊API
Notifier是pyinotify模塊最重要的類,用來讀取通知和處理事件,默認情況下,Notifier處理事件的方式是打印事件。
Notifier類在初始化時接受多個參數,但是只有WatchManager對象是必須傳遞的參數,WatchManager對象保存了需要監視的文件和目錄,以及監視文件和目錄的哪些事件,Notifier類根據WatchManager對象中的配置來決定如何處理事件。
#!/usr/bin/env python3 import pyinotify wm = pyinotify.WatchManager() # 創建WatchManager對象 wm.add_watch('/tmp',pyinotify.ALL_EVENTS) # 添加要監控的目錄,以及要監控的事件,這里ALL_EVENT表示所有事件 notifier = pyinotify.Notifier(wm) # 交給Notifier進行處理 notifier.loop() # 循環處理事件
事件標志
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
PS:python3中 IN_CLOSE好像被移除了
事件處理
前面的例子,我們使用的都是默認的事件處理方式:打印在屏幕上,而很多情況下我們需要定制事件的處理方式,來實現特殊的功能。
定制事件需要繼承ProcessEvent類,針對需要處理的事件編寫 process_事件名(self,event) 函數即可
import pyinotify multi_event = pyinotify.IN_OPEN | pyinotify.IN_CLOSE_NOWRITE # 監控多個事件 wm = pyinotify.WatchManager() # 創建WatchManager對象 class MyEventHandler(pyinotify.ProcessEvent): # 定制化事件處理類,注意繼承 def process_IN_OPEN(self,event): # 必須為process_事件名稱,event表示事件對象 print('OPEN',event.pathname) # event.pathname 表示觸發事件的文件路徑 def process_IN_CLOSE_NOWRITE(self,event): print('CLOSE_NOWRITE',event.pathname) handler = MyEventHandler() # 實例化我們定制化后的事件處理類 notifier = pyinotify.Notifier(wm,handler) # 在notifier實例化時傳入,notifier會自動執行 wm.add_watch('/tmp',multi_event) # 添加監控的目錄,及事件 notifier.loop()