1. 程式人生 > >使用pyinotify 監控多資料夾多目錄是否有新檔案生成內容是否變化

使用pyinotify 監控多資料夾多目錄是否有新檔案生成內容是否變化

檢測一個目錄A是否有遠端服務傳過來的檔案,有的話呼叫相關服務去解析或者處理此檔案,處理完生成處理報告結果到另一個目錄B,這就需要同時監控A、B兩個目錄是否有新檔案生成,A生成了新檔案就本地處理,B生成了新檔案要傳送出去。
找到了pyinotiy這個模組,Pyinotify是一個簡單而有用的Python模組,用於在Linux中實時監控檔案系統的更改 ,繫結三個系統呼叫,並支援其上的實現,提供了一個共同和抽象的手段來操縱這些功能。
作為系統管理員,您可以使用它來監視目標感興趣的更改,如Web目錄或應用程式資料儲存目錄及其他目錄。

依賴關係
為了使用pyinotify ,您的系統必須執行:
Linux核心2.6.13或更高版本
Python 2.4或更高版本
如何在Linux中安裝Pyinotify
首先檢查系統上安裝的核心和Python版本,如下所示:

# uname -r 
# python -V

一旦滿足依賴關係,我們將使用pip來安裝pynotify 。 在大多數Linux發行版中,如果您使用從python.org下載的Python 2> = 2.7.9或Python 3> = 3.4二進位制檔案, Pip已經安裝,否則安裝如下:

# yum install python-pip      [On CentOS based Distros]
# apt-get install python-pip  [On Debian based Distros]
# dnf install python-pip      [On Fedora 22+]

現在,像這樣安裝pyinotify:

# pip install pyinotify

它將從預設儲存庫安裝可用版本,如果您希望具有最新的穩定版本的pyinotify ,請考慮將其克隆為git倉庫,如下所示。

# git clone https://github.com/seb-m/pyinotify.git
# cd pyinotify/
# ls
# python setup.py install

指令碼程式碼:

#!/usr/bin/python
# coding=UTF-8
import os
import pyinotify
import threading
from time import ctime,sleep

#監控檔案目錄是否有新檔案傳來,有的話提交給本地服務
class OnWriteHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event): #函式名以"process_"開頭,後面跟註冊的監測型別
        #os.system('echo '+'create file:%s'%(os.path.join(event.path,event.name))) #之後用於nohup輸出
        print "new file: %s " % os.path.join(event.path,event.name) #列印
        os.system('sampleserv submit ' + '%s'%(os.path.join(event.path, event.name))) #提交給檔案處理服務,此處呼叫你自己的介面或者處理

def auto_compile(path='./samples'):
    wm = pyinotify.WatchManager()
    mask = pyinotify.IN_CREATE #監測型別,如果多種用|分開,pyinotify.IN_CREATE | pyinotify.IN_DELETE
    notifier = pyinotify.Notifier(wm, OnWriteHandler())
    wm.add_watch(path, mask,rec=True,auto_add=True)
    print '==> Start monitoring %s (type c^c to exit)' % path
    while True:
        try:
            notifier.process_events()
            if notifier.check_events():
                notifier.read_events()
        except KeyboardInterrupt:
            notifier.stop()
            break

#監控本地檔案處理服務檢測報告是否完成,完成的話傳送
class OnAnalyzerHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        if event.name == 'report.json':
            print "new analyze reports: %s" % os.path.join(event.path, event.name)
            #呼叫介面傳送報告,此處為呼叫你自己的介面或處理2

def wait_analyze(path='/home/analyses/'):
    wm = pyinotify.WatchManager()
    mask = pyinotify.IN_CREATE
    notifier = pyinotify.Notifier(wm, OnAnalyzerHandler())
    wm.add_watch(path, mask, rec=True, auto_add=True)
    print 'Start monitoring %s ' % path
    while True:
      try:
        notifier.process_events()
        if notifier.check_events():
          notifier.read_events()
      except KeyboardInterrupt:
        notifier.stop()
        break


threads = []
t1 = threading.Thread(target=auto_compile,args=('./samples',))
threads.append(t1)
t2 = threading.Thread(target=wait_analyze,args=('/home/prism/.cuckoo/storage/analyses/',))
threads.append(t2)

def threads_join(threads):
    '''
    令主執行緒阻塞,等待子執行緒執行完才繼續,使用這個方法比使用join的好處是,可以ctrl+c kill掉程序
    '''
    for t in threads:
        while 1:
            if t.isAlive():
                sleep(10)
            else:
                break

if __name__ == "__main__":
    for t in threads:
            t.setDaemon(True)
            t.start()

    threads_join(threads)
    print "all over %s" %ctime()