ファイルシステムへのイベントをチャッチして仕掛けを組めるツール
本家様 https://github.com/rvoicilas/inotify-tools/wiki

inotify-tools/FileTransfer
inotify-tools/WindowsPC

inotify-tools/programming

インストール

CentOS7はepelリポジトリからインストール可能で、epelリポジトリの組み込みはここを参照yum

[root@c ~]# yum --enablerepo=epel install inotify-tools

インストールされるプログラムは「/usr/bin/inotifywait」と「/usr/bin/inotifywatch」の2つ。

inotifywait

特定フォルダ、ファイルを監視して通知する
下記の例は /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で感知したファイルを引数に、スクリプトを動かしてみる。
inotifywait自体は感知するだけで、後に連携させることはなく、その感知したファイル名を提示するのみ。
この提示するファイル名を拾う仕組みが必要みたい。

オプションの「-mrq」は、「-m」はmonitorの意で継続的に監視します。指定がないと一回だけで終了
「-r」はrecursiveの意味で指定したフォルダより深い階層も監視します。っが配下のフォルダ数に応じてメモリー消費が増える
「-q」はquietの意味。指定すると余計なログを出さない

「--format」は書き出す文字列のフォーマットを意味する。「%T」は時刻を表わす。これはさらに「--timefmt」で定義する
「%w」は監視対象を含めてのフォルダを示す。「%f」はイベント対象となったファイルを示す。

#!/bin/bash
inotifywait -mrq --format '%T %w%f (%e)' --timefmt '%F %T' -e close_write /share \
| while [ 1 ]; do
  messages="";
  while read -t 0.01 line; do
     messages=$line
  done

  if [ -n "$messages" ]; then
    echo $messages
    f=`echo $messages|cut -d' ' -f3`
    cp $f /share2
  fi
done

「read -t 0.1」は、0.1秒間隔で監視します。
inotifywaitはそんな間隔なしにファイルをwatchできるのだが、それに続くshell scriptに「read」を使ったため0.1だと0.1秒間に2つのwatchが発生すれば、後者のファイルは無視されます。


トップ   編集 添付 複製 名前変更     ヘルプ   最終更新のRSS
Last-modified: 2017-05-11 (木) 23:11:53 (97d)