カーネル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つとして提供されているようで、それを元にプログラムを作成することもできます。
独自のファイル監視アプリケーションを作ったり、あるディレクトリにファイルが作られたらそれをトリガーとして何かの処理を行うなど、色々なアプリケーションに応用できると思います。
とても簡単に使え、便利な機能なのでサーバー管理をする際には覚えておいてはいかがでしょうか。
関連記事
[PHP] inotify関数を使ってログを監視するスクリプトを作ろう
Linux上でファイルを削除してしまった際にさっくり復活できるextundelete
NFSマウントした領域内でPHPのsession_startを実行すると異様に重い件
簡単にファイル検索をするためのlocateコマンドオリジナル活用法
不要なファイルやディレクトリを削除できる「tmpwatch」コマンド