inotifywaitを使うと、「指定したファイル」や「指定したディレクトリ内のファイル」に対する読み書きアクセスを検知することができる。
まず簡単な例として、ディレクトリ内のファイルへのアクセスを監視し続け、標準出力に結果を吐き出させる例を作成。
なお、 -m
オプションをつけて、Ctrl + C を押すまで監視し続けてみる
$ inotifywait -m --exclude '.Trash' /home/vm/Desktop/src/ Setting up watches. Watches established. /home/vm/Desktop/src/ OPEN,ISDIR /home/vm/Desktop/src/ ACCESS,ISDIR /home/vm/Desktop/src/ ACCESS,ISDIR /home/vm/Desktop/src/ CLOSE_NOWRITE,CLOSE,ISDIR /home/vm/Desktop/src/ OPEN test01.txt /home/vm/Desktop/src/ OPEN,ISDIR /home/vm/Desktop/src/ ACCESS,ISDIR /home/vm/Desktop/src/ ACCESS,ISDIR /home/vm/Desktop/src/ CLOSE_NOWRITE,CLOSE,ISDIR /home/vm/Desktop/src/ ACCESS test01.txt /home/vm/Desktop/src/ CLOSE_NOWRITE,CLOSE test01.txt /home/vm/Desktop/src/ OPEN test01.txt /home/vm/Desktop/src/ CREATE .goutputstream-C2GT7Z /home/vm/Desktop/src/ OPEN .goutputstream-C2GT7Z /home/vm/Desktop/src/ ATTRIB .goutputstream-C2GT7Z /home/vm/Desktop/src/ CLOSE_WRITE,CLOSE test01.txt /home/vm/Desktop/src/ MODIFY .goutputstream-C2GT7Z /home/vm/Desktop/src/ MOVED_FROM .goutputstream-C2GT7Z /home/vm/Desktop/src/ MOVED_TO test01.txt /home/vm/Desktop/src/ CLOSE_WRITE,CLOSE test01.txt 〜 以下省略 (Ctrl + C で終了できる) 〜
このキャプチャ例は、nautilusでディレクトリを開き、テキストファイルをgeditで編集し保存しただけのアクションで検出されたイベントだ。 検出イベントがあまりにも多すぎる…
抽出するイベントを -e
オプションで絞り込んでみる
geditでファイルを開き、保存した場合
$ inotifywait -m --exclude '.Trash' -e MODIFY -e CREATE -e MOVED_TO /home/vm/Desktop/src/ cc /home/vm/Desktop/src/ CREATE .goutputstream-TNN57Z XX /home/vm/Desktop/src/ MODIFY .goutputstream-TNN57Z cc /home/vm/Desktop/src/ MOVED_TO test01.txt
vimでファイルを開き、保存した場合
$ inotifywait -m --exclude '.Trash' -e MODIFY -e CREATE -e MOVED_TO /home/vm/Desktop/src/ /home/vm/Desktop/src/ CREATE .test01.txt.swp /home/vm/Desktop/src/ CREATE .test01.txt.swx /home/vm/Desktop/src/ CREATE .test01.txt.swp /home/vm/Desktop/src/ MODIFY .test01.txt.swp /home/vm/Desktop/src/ MODIFY .test01.txt.swp /home/vm/Desktop/src/ MODIFY .test01.txt.swp /home/vm/Desktop/src/ CREATE 4913 /home/vm/Desktop/src/ MOVED_TO test01.txt~ /home/vm/Desktop/src/ CREATE test01.txt /home/vm/Desktop/src/ MODIFY test01.txt /home/vm/Desktop/src/ MODIFY test01.txt /home/vm/Desktop/src/ MODIFY .test01.txt.swp
コマンドラインのcpコマンドでファイルをコピーした場合
$ inotifywait -m --exclude '.Trash' -e MODIFY -e CREATE -e MOVED_TO /home/vm/Desktop/src/ /home/vm/Desktop/src/ CREATE test04.txt /home/vm/Desktop/src/ MODIFY test04.txt
ファイルの保存、ファイルのコピーという一つのアクションを起こすと、複数のイベントがキャプチャされる。ある特定のイベントをキャプチャしたい場合、さらに文字列を抜き出すということをすれば…
test.sh (MODIFYイベントのみを抜き出すスクリプト)
#/bin/sh inotifywait -m --exclude '.Trash' -e MODIFY -e CREATE -e MOVED_TO /home/vm/Desktop/src/ | while read str do if [ "`echo $str | grep 'MODIFY'`" ] then echo "一致 ${str}" else echo "不一致 ${str}" fi done
このスクリプトを使っても、やはり、「保存」という一つのアクションに対して、一つのイベント抽出は難しい。
最終的に、inotifywait の常駐監視機能(-m)オプションを使わないことで解決
test-02.sh (スクリプト側のwhileループで常駐監視する例)
#/bin/sh while : do inotifywait --exclude '.Trash' -e MODIFY -e CREATE -e MOVED_TO /home/vm/Desktop/src/ > /dev/null 2>&1 gdialog --title "inotifywait" --yesno '/home/vm/Desktop/src/ のファイルが変更されました\n' 0 0 RESPONSE=$? # yes=0, no=1, esc=255 case $RESPONSE in 0) ./user_command.sh;; 1) ;; 255) ;; esac done