Blanktar

  1. top
  2. blog
  3. 2013
  4. 03

pythonでinotifyを使ってみる。

inotifyっての、ご存知でしょうか。 linux karnelの機能で、変更されたファイルを通知してくれるシステム。 なんだかよく分からないけれど、なんだか楽しそうな気がしたので、触ってみました。

追記

wm.rm_watchとしなければならないところをwm.rem_watchとしてしまっていたのを修正。 申し訳ない

追記

シェルからinotifyを利用する方法も書きました。 手軽に確認したいだけとかならシェルのがいいかも。

インストール

pyinotifyってライブラリを使ってみます。 portageにあったので、今回はそれを使用。

$ sudo emerge dev-python/pyinotify

これだけ。 他のOSなんかを使ってる方は、githubにあるやつをどうぞ。

とりあえず使う

import time
    
import pyinotify


class Handler(pyinotify.ProcessEvent):
    # イベント通知を受け取るモノ。
    # process_フラグ名(self, event) って関数を用意しておけばいいみたいね。

    def process_IN_CREATE(self, event):
        # ファイルやディレクトリが追加された時に呼ばれる

        print 'Create :'
        print event

    def process_IN_DELETE(self, event):
        # ファイルやディレクトリが削除された時に呼ばれる

        print 'Delete :'
        print event

    def process_default(self, event):
        # それ以外の場合に呼ばれる

        print event.maskname
        print event


wm = pyinotify.WatchManager()

# 監視スレッドを作って、走らせる。
#  Handler()の()に注意。インスタンスを渡します。
notifier = pyinotify.ThreadedNotifier(wm, Handler())
notifier.start()

# 監視するイベントの種類
#  フラグの意味は後述する表を参照。
mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY

# 監視対象の追加
wdd = wm.add_watch('/tmp', mask)

time.sleep(30)

# 監視対象の削除
#  `wdd['/tmp']`みたいにすれば特定のディレクトリだけ削除できる。
#  ちなみに、python3.xの場合は`list(wdd.values())`としなければいけないみたい。
wm.rm_watch(wdd.values())

# 監視スレッドの終了
#  これを忘れるとプログラムが終了しません。
#  そのまえで例外で終了しちゃったりすると、killするしかなくなるみたい。
notifier.stop()

こんな感じ。ほぼsourceforgeのマネ。 30秒間だけ/tmpの変更(ファイルの追加と削除)を監視します。

フラグ一覧

通知関連

名称発生するタイミング
IN_ACCESSファイルアクセスがあった時
IN_ATTRIBメタデータに変更があった時
IN_CLOSE_WRITE書き込み用に開かれたファイルが閉じられた時
IN_CLOSE_NOWRITE書き込み以外のために開かれたファイルが閉じられた時
IN_CREATEファイルやディレクトリが作られた時
IN_DELETEファイルやディレクトリが消された時
IN_DELETE_SELF監視しているファイルやディレクトリそのものが消された時
IN_MODIFYファイル内容が変更された時
IN_MOVE_SELF監視しているファイルやディレクトリそのものが移動された時
IN_MOVED_FROMファイルやディレクトリがどこかから移動されてきた時
IN_MOVED_TOファイルやディレクトリがどこかに移動された時
IN_OPENファイルが開かれた時
IN_Q_OVERFLOWイベントキューがオーバーフローを起こした時
IN_UNMOUNT監視しているファイルやディレクトリを含むファイルシステムがアンマウントされた時

その他

名称内容
IN_DONT_FOLLOWシンボリックリンクを辿らない(Linux Kernel 2.6.15以降)
IN_ISDIRディレクトリに対して設定する・・・?
IN_MASK_ADD既に設定されているディレクトリに対して二重に設定した場合、上書きではなく追加として設定する (Linux Kernel 2.6.14以降)
IN_ONLYDIR与えられた引数がディレクトリの場合のみ監視する(Linux Kernel 2.6.15以降)

参考: