ファイルシステムへのイベントをチャッチして仕掛けを組めるツール
本家様 https://github.com/rvoicilas/inotify-tools/wiki
inotify-tools/FileTransfer
inotify-tools/WindowsPC
CentOS7はepelリポジトリからインストール可能で、epelリポジトリの組み込みはここを参照yum
[root@c ~]# yum --enablerepo=epel install inotify-tools
インストールされるプログラムは「/usr/bin/inotifywait」と「/usr/bin/inotifywatch」の2つ。
特定フォルダ、ファイルを監視して通知する
下記の例は /tmp に対してのイベントを監視して通知します。
[root@c ~]# inotifywait -m -r /tmp -q --format '%T %w%f (%e)' --timefmt '%F %T'
ファイルを作ってみると(touch /tmp/sample)
2015-06-28 13:28:38 /tmp/sample (CLOSE_WRITE,CLOSE)
と記録される。っが、ファイルのモードの変更(chmod 600 /tmp/sample)やら所有者の変更(chown saber /tmp/sample)は記録されなかった。マニュアルには-eとして定義しなければ、access、modify、attrib、close_write、close_nowrite、close、open、moved_to、moved_from、move、create、delete、delete_self、unmountの全てがイベント監視対象とされているのだが...
-e|--event <event1> [ -e|--event <event2> ... ]
Listen for specific event(s). If omitted, all events are
listened for.
まぁ、いい。全てを記載してみる。
[root@c ~]# inotifywait -m -r /tmp -q --format '%T %w%f (%e)' --timefmt '%F %T' -e access -e modify \
-e attrib -e close_write -e close_nowrite -e close -e open -e moved_to -e moved_from -e move -e create \
-e delete -e delete_self -e unmount
そして、ファイルを作ってみる(touch /tmp/sample)
2015-06-28 13:44:49 /tmp/sample (CREATE)
2015-06-28 13:44:49 /tmp/sample (OPEN)
2015-06-28 13:44:49 /tmp/sample (ATTRIB)
2015-06-28 13:44:49 /tmp/sample (CLOSE_WRITE,CLOSE)
次に編集してみる(echo 'This is sample.' > /tmp/sample)
2015-06-28 13:46:30 /tmp/sample (MODIFY)
2015-06-28 13:46:30 /tmp/sample (OPEN)
2015-06-28 13:46:30 /tmp/sample (MODIFY)
2015-06-28 13:46:30 /tmp/sample (CLOSE_WRITE,CLOSE)
ファイルモードを変更してみる(chmod 600 /tmp/sample)
2015-06-28 13:47:21 /tmp/sample (ATTRIB)
所有者を変更してみる(chown saber /tmp/sample)
2015-06-28 13:48:11 /tmp/sample (ATTRIB)
削除(rm /tmp/sample)
2015-06-28 13:49:18 /tmp/sample (DELETE)
と一連の操作は記録される。
留意
/home を対象とすると
Failed to watch /home; upper limit on inotify watches reached!
Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'.
と言われる。監視対象が多いとエラーになる。適時/proc/sys/fs/inotify/max_user_watchesの値を変更すればいい。
[root@c ~]# cat /proc/sys/fs/inotify/max_user_watches
8192
[root@c ~]# echo 40960 > /proc/sys/fs/inotify/max_user_watches
*ただし、監視一つ当たり 1 kB のメモリーが消費される(スワップにはできない)。なので要注意。
対象としたいパスのディレクトリの数は下記で調べられる。
[root@c /]# find /home/ -type d -print| wc -l
263712
[root@c /]#
これを元にして、
[root@c ~]# echo 270000 > /proc/sys/fs/inotify/max_user_watches
[root@c ~]# inotifywait -m -r /home -q --format '%T %w%f (%e)' --timefmt '%F %T' -e close_write
とするとエラーは発生しなくなった。ただし270000 -> 270000 kB -> 263MB ほどメモリーが消費される。
参照先:http://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached
inotifywaitで感知したファイルを引数に、スクリプトを動かしてみる。
inotifywait自体は感知するだけで、後に連携させることはなく、その感知したファイル名を提示するのみ。
この提示するファイル名を拾う仕組みが必要みたい。
オプションの「-mrq」は、「-m」はmonitorの意で継続的に監視します。指定がないと一回だけで終了
「-r」はrecursiveの意味で指定したフォルダより深い階層も監視します。っが配下のフォルダ数に応じてメモリー消費が増える
「-q」はquietの意味。指定すると余計なログを出さない
「--format」は書き出す文字列のフォーマットを意味する。「%T」は時刻を表わす。これはさらに「--timefmt」で定義する
「%w」は監視対象を含めてのフォルダを示す。「%f」はイベント対象となったファイルを示す。
|
「read -t 0.1」は、0.1秒間隔で監視します。
inotifywaitはそんな間隔なしにファイルをwatchできるのだが、それに続くshell scriptに「read」を使ったため0.1だと0.1秒間に2つのwatchが発生すれば、後者のファイルは無視されます。