inotify-toolsでファイルやディレクトリを監視する


Linux2.6から追加されたinotifyというAPIは、ファイルやディレクトリーでオープン、クローズ、移動/名前変更、削除、作成、属性の変更などといったファイルシステムイベントを監視することができます。

inotify API群を利用して自分でファイルシステムイベント監視プログラムを実装することができますが、
今回は、inotify-toolsというinotifyを利用したファイルシステムイベント監視ツールを使用します。

## inotifyイベント
inotifyでは対象のファイルまたはディレクトリに対して以下のファイルシステムイベントが監視できます。
※対象がディレクトリの場合は、ディレクトリ自身とその配下のファイルが対象となります。

| イベント名      |イベント発生タイミング|
|:--------------|:------------------------|
| ACCESS        |readなどでアクセスされた|
| MODIFY        |writeなどでファイル内容が変更された|
| ATTRIB        |アクセス件やタイムスタンプなどのメタデータが変更された|
| CLOSE_WRITE   |書き込みモードでオープンされた後クローズされた|
| CLOSE_NOWRITE |読み込みモードオープンされた後クローズされた|
| CLOSE         |オープンモードに関わらずクローズされた|
| OPEN          |オープンされた|
| MOVED_TO      |対象ディレクトリ内へ移動された|
| MOVED_FROM    |対象ディレクトリ内から移動された|
| MOVE          |対象自身が移動された|
| CREATE        |対象ディレクトリ内で新規作成された|
| DELETE        |対象ディレクトリ内で削除された|
| DELTELE_SELF  |対象自身が削除された|
| UNMOUNT       |対象を含むファイルシステムがアンマウントされた|


## inotify-tools
inotify-toolsはinotifyを使ったコマンドラインツールで、以下の２つから構成されます。

* inotifywait
	* ファイルシステムイベントを待ち、発生時に表示する
* inotifywatch
	* ファイルシステムイベントの統計を表示

### インストール
inotify-toolsは以下のようにaptからインストールします。

```console
$ sudo apt-get install inotify-tools
```

## inotifywait
### 使い方

```console 
$ inotifywait [option] <file> [ ... ]
```

### 使用例

試しにファイルsample.txtの書き換えを監視してみます。
inotifywaitはバックグラウンドで動かします。

```shell-session
$ echo hoge > sample.txt
$ inotifywait sample.txt &
[1] 7071
$ echo huga > sample.txt
sample.txt MODIFY
[1]+  Done                    inotifywait sample.txt
```

ファイル内容変更の`MODIFY`が通知されました。
いや、MODIFYだけっておかしくないか？

notifywaitは`-m`オプションをつけないと一度しかイベント通知しません。
`-m`オプションをつけて再度確認します。

```
$ inotifywait -m sample.txt &
[1] 7105
$ echo huga > sample.txt
sample.txt OPEN
sample.txt MODIFY
sample.txt CLOSE_WRITE,CLOSE
```

めでたく`OPEN`,`MODIFY`,`CLOSE_WRITE`,`CLOSE`が通知されました。

その他色々とファイル操作して、どんな通知されるか見てみましょう。

```shell-sesison
$ mkdir hoge
$ inotifywait -m hoge &
$ cd hoge/
$ touch sample.txt
hoge/ CREATE sample.txt
hoge/ OPEN sample.txt
hoge/ ATTRIB sample.txt
hoge/ CLOSE_WRITE,CLOSE sample.txt
$ echo hoge >sample.txt
hoge/ MODIFY sample.txt
hoge/ OPEN sample.txt
hoge/ MODIFY sample.txt
hoge/ CLOSE_WRITE,CLOSE sample.txt
$ cat sample.txt
hoge/ OPEN sample.txt
hoge/ ACCESS sample.txt
hoge
hoge/ CLOSE_NOWRITE,CLOSE sample.txt 
$ chmod 666 sample.txt
hoge/ ATTRIB sample.txt
$ mv sample.txt test.txt
hoge/ MOVED_FROM sample.txt
hoge/ MOVED_TO test.txt
$ rm test.txt
hoge/ DELETE test.txt
$ cd ../
$ mv hoge fuga
hoge/ MOVE_SELF
$ rmdir fuga
hoge/ DELETE_SELF
```

`UMOUNT`以外は網羅できたかと思います。

### 出力フォーマット
`--format`オプションをつけることで、出力結果のフォーマットが設定できます。
また、その時`%T`で日時を付与したときは`--timefmt`で[strftime](http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/strftime.3.html)と同様の日時フォーマットも設定できます。

```shell-session
$ mkdir hoge
$ inotifywait -m --format '%T %w%f (%e)' --timefmt '%F %T' hoge &
$ touch hoge/sameple.txt
2014-05-21 15:58:33 hoge/sameple.txt (OPEN)
2014-05-21 15:58:33 hoge/sameple.txt (ATTRIB)
2014-05-21 15:58:33 hoge/sameple.txt (CLOSE_WRITE,CLOSE)
```

### その他オプション

* `-h`:ヘルプの表示
* `-r`:対象がディレクトリ時に対象を再帰的に掘っていく
* `-c`:通知結果をcsvで表示
* `-e <event>`:eventで指定したイベントのみを通知するようにフィルタリングする
*  `-t <seconds>`:`-m`オプションを付けない場合にseconds秒後に監視を終了する
* `-d`:デーモン化して動作する。結果は`-o`オプション指定ファイルか、`-s`オプションでsyslogに書き込む

## inotifywatch
### 使い方

```console 
$ inotifywatch [option] <file> [ ... ]
```

### 使用例
`ctrl+c`でinotifywatchを停止するまで発生したファイルシステムイベントの統計情報が表示されます。

```shell-session
$ inotifywatch sample.txt &
[1] 7434
$ Establishing watches...
Finished establishing watches, now collecting statistics.
touch sample.txt
$ fg
inotifywatch sample.txt
^Ctotal  attrib  close_write  open  filename
3      1       1            1     sample.txt
```

## 参考URL

* Man page of INOTIFY(http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/inotify.7.html)
* inotify で Linux ファイルシステムのイベントを監視する(http://www.ibm.com/developerworks/jp/linux/library/l-inotify/)
* inotify-tools(https://github.com/rvoicilas/inotify-tools/wiki)