inotifyを使ってファイルやディレクトリに起きたイベントを簡単に監視する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

カーネル2.6.13からファイルの状態やイベントを監視するinotifyという機能が使えるようになっています。

(カーネルの機能の一部として実装されている)


詳細は下記が参考になると思います。


inotify を使ってファイルシステムのアクティビティーを監視する @ IBM


で、使ってみたら結構これが面白い。

応用すれば、あるファイルを削除されたり変更されたらアラートを発砲するとか、ディレクトリ内にどのような操作が行われたのかを見ることができます。


予断ですが、ファイル監視といえばFAM(file alteration monitor)というツールもあります。

使ったことないのですが、ファイル監視をしてくれるというものらしく、初めはファイルを監視したいという要件を満たすために、FAMを使ってみようかなと思っていたのですが、日本語の情報が乏しいのと、RedHat系OSでは提供されなくなった(RedHat4以降RPM版が存在しない)みたいで、今回のinotifyを使うにいたりました。



inotify-toolsをインストールする


inotifyの機能をコマンドラインで使うためには、inotify-toolsというコマンドをインストールする必要があります。

まずは、これをインストールしてみましょう。

検証した環境ですがCentOS5.2上で試しており、RPM版が提供されていないようなので、ソースからインストールしました。


1. inotify-toolsをダウンロードする


inotify-toolsはsourceforge よりダウンロードできます。



2. inotify-toolsをインストールする


インストールすると言っても、Linuxお決まりのパターンでいけます。


# tar -xvzf inotify-tools-3.13.tar.gz

# cd inotify-tools-3.13

# ./configure

# make

# make install


inotify-toolsを使ってみよう


inotify-toolsをインストールすると、inotifywaitとinotifywatchという2つのコマンドが利用可能になります。

inotifywaitは、監視対象のファイルやディレクトリへのイベントをリアルタイムに表示してくれ、inotifywatchはそのイベント数の合計をサマリにして表示してくれます。

まずは、わかりやすいinotifywaitコマンドを使ってみましょう。


1. inotifywaitコマンドの使い方


オプションはいくつかあるのですが、一番シンプルな使い方をして見ましょう。

まず、あるターミナル(A)で以下を実行してみます。


# inotifywait -r -m /home/hoge

上記は、hogeユーザーのホームディレクトリを監視しています。

このままでは、ターミナル(A)上は何も変化がおきません。

そこで、今度は別のターミナル(B)を使って新規にhogeユーザーでログインしてみます。


/home/hoge/ OPEN,ISDIR
/home/hoge/ CLOSE_NOWRITE,CLOSE,ISDIR
/home/hoge/ OPEN .bash_profile
/home/hoge/ ACCESS .bash_profile
/home/hoge/ CLOSE_NOWRITE,CLOSE .bash_profile
/home/hoge/ OPEN .bashrc
/home/hoge/ ACCESS .bashrc
/home/hoge/ CLOSE_NOWRITE,CLOSE .bashrc
/home/hoge/ OPEN .bash_history
/home/hoge/ ACCESS .bash_history
/home/hoge/ CLOSE_NOWRITE,CLOSE .bash_history
/home/hoge/ OPEN .bash_history
/home/hoge/ ACCESS .bash_history
/home/hoge/ CLOSE_NOWRITE,CLOSE .bash_history

すると先ほどのinotifywaitコマンドを実行しているターミナル(A)にずらずらと文字列が出てきました。

これが、hogeディレクトリに対して行われたイベントのログです。


見てみると、.bash_profileなどの環境設定ファイルが読み込まれていることがわかります。

続いて、別で開いたターミナル(B)上でファイルを作成してみます。


# touch test.txt

すると、元のターミナル(A)上には下記のようなログが出力されます。


/home/hoge/ CREATE test.txt
/home/hoge/ OPEN test.txt
/home/hoge/ ATTRIB test.txt
/home/hoge/ CLOSE_WRITE,CLOSE test.txt

touchコマンドだけでも、その内部的な動作はファイルを作成し、ファイルを開いて属性を変更している様子がわかります。


このように、inotifywaitコマンドは監視対象上のディレクトリやファイルへの変更を監視してくれ、何か操作が行われた際のイベント情報を出力してくれます。



2. inotifywatchコマンドの使い方


次にinotifywatchコマンドです。

こちらは、説明したとおりイベント情報をサマリにして出力してくれます。


先ほどのサーバーへのログインして、ファイルを作成するという一連の操作を繰り返してみます。

まず同じように、一方のターミナル(A)でinotifywatchコマンドを実行


# inotifywatch -r /home/hoge
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.

ここで別のターミナル(B)を開いてhogeユーザーでログインし、touchコマンドでtest.txtを作成します。

そして、元のターミナル(A)を「Ctrl + C」で終了させます。

すると・・・


# inotifywatch -r /home/hoge
Establishing watches...
Finished establishing watches, now collecting statistics.
ttotal access modify attrib close_write close_nowrite open filename
26    6     1     1      2       7      9  /home/hoge/


と、このように種類ごとにいくつのイベントが発生したかをサマリにして表示してくれます。

ちょっと使い道がわかりませんが・・・。



inotifywaitコマンドを使って色々監視してみる


1. 特定のファイルの監視をしてみる


先ほどはディレクトリの監視でしたが、特定のファイルの監視ももちろん可能です。


# inotifywait -m /home/hoge/test.txt

としている状態で、別のターミナルから


# echo "abc" >> test.txt

としてみると、


/home/hoge/test.txt OPEN
/home/hoge/test.txt MODIFY
/home/hoge/test.txt CLOSE_WRITE,CLOSE

というようなイベントログが出力されます。



2. サブディレクトリ内のログも監視する


inotifywaitコマンドに-rオプションをつけて実行することで問題なく監視することができます。

例えば、先ほどのhogeディレクトリ以下にあるtmpディレクトリ内にファイルを作成した場合もイベントをキャッチしてくれます。


# inotifywait -r -m /home/hoge/
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
/home/hoge/tmp/ CREATE test.txt
/home/hoge/tmp/ OPEN test.txt
/home/hoge/tmp/ ATTRIB test.txt
/home/hoge/tmp/ CLOSE_WRITE,CLOSE test.txt

そのディレクトリだけを監視したい場合は、-rオプションを取り除いてモニタリングしておけばよいでしょう。



3. 監視対象のファイルを削除したら?


監視対象のファイルを削除してしまったらどうなるでしょうか。


# inotifywait -m /home/hoge/test.txt
Setting up watches.
Watches established.
/home/hoge/test.txt DELETE_SELF
/home/hoge/test.txt IGNORED

最後にファイルが削除されたイベントログが出力されています。

同名のファイルを作り直しても、もちろん復活はしません。



4. アプリからの操作ももちろん監視できる


例えば、こういうPHPスクリプトを書いておき


<?php
$fp = fopen("/home/hoge/foo.txt", "a");
fwrite($fp, "xyz");
fclose($fp);
?>

実行してみると・・・


# inotifywait -m /home/hoge/
Setting up watches.
Watches established.
/home/hoge/ CREATE foo.txt<
/home/hoge/ OPEN foo.txt
/home/hoge/ MODIFY foo.txt
/home/hoge/ CLOSE_WRITE,CLOSE foo.txt

ファイルが作られているイベントログが出力されます。


inotifyはそもそもカーネルのAPIの1つとして提供されているようで、それを元にプログラムを作成することもできます。

独自のファイル監視アプリケーションを作ったり、あるディレクトリにファイルが作られたらそれをトリガーとして何かの処理を行うなど、色々なアプリケーションに応用できると思います。


とても簡単に使え、便利な機能なのでサーバー管理をする際には覚えておいてはいかがでしょうか。