以前、簡易にディレクトリの同期を行う方法としてlsyncdを使った方法を調べましたが、単純にrsyncするだけではなくてもうちょっと手の込んだ事がやりたくなってきたのでlsyncdと同じinotifyベースで動作するincronをというソフトウェアを試してみました。
ファイル/ディレクトリの変更に応じて任意のジョブを実行するincron - SourceForge.JP Magazine
こうした伝統的なcronで行えるのが時刻指定型のジョブ実行であるのに対して、ファイルシステムの変更を検出して指定のコマンドを実行させるというコンセプトで作られたcronクローンの一種に incron というツールが存在する(正式名称はinotify cron)。incronを使用するための設定としては、どのようなファイル/ディレクトリの変更を監視対象とするかおよび、そこでの変更発生時に実行すべきジョブの登録が必要となる。
以下は作業メモ。
† インストール
ソースからインストールしなければならないかと思いきや、CentOS 5.4ではyumでいけました。
# yum install incron
# /etc/init.d/incrond start
† 環境の準備
今回は/tmp/test1というディレクトリを作って監視を仕掛けてみます。
% mkdir /tmp/test1
% incrontab -e
incrontabのエディタが起動したら、下記の内容を打ち込みます。
/tmp/test1 IN_ALL_EVENTS,IN_NO_LOOP /tmp/test1.sh "$@" "$#" "$%"
$@、$#、$%は特殊変数になっていて、それぞれディレクトリ名、ファイル名、イベント名に読み替えられるようになっています。
ディレクトリに変化があったときに呼び出されるスクリプトは単純にログを取るものを用意しました。
/tmp/test1.sh
#!/bin/bash
. /etc/profile
. ~/.bash_profile
SCRIPT_DIR=`dirname $0`
cd $SCRIPT_DIR
INCRON_DIR="$1"
INCRON_FILE="$2"
INCRON_EVENT="$3"
echo "`date`,$INCRON_DIR,$INCRON_FILE,$INCRON_EVENT" >> test1.log
ちなみにコマンドはPATH等の環境変数がほとんど入っていない状態で起動されるので、そのあたりをセットするのを忘れないようにした方が良さそうです。/var/log/cronに起動のログが残っているのに、うまくコマンドが起動されなくてちょっとハマりました。
† 実際に動作させてみる
監視対象となっているディレクトリに対して下記のような動作を加えてみました。
% touch /tmp/test1/aa
% cd /tmp/test1
% vi bb
% cd ..
% touch cc
% mv cc test1
記録されたログファイルはこんな感じ。
IN_ALL_EVENTSだとかなりイベントが飛んでくるので、テストが済んだら必要なものに絞った方がよさそう。
/tmp/test1.log
Sat Dec 5 17:27:58 JST 2009,"/tmp/test1","","IN_OPEN,IN_ISDIR"
Sat Dec 5 17:27:59 JST 2009,"/tmp/test1","","IN_OPEN,IN_ISDIR"
Sat Dec 5 17:27:59 JST 2009,"/tmp/test1","","IN_CLOSE_NOWRITE,IN_ISDIRR"
Sat Dec 5 17:28:29 JST 2009,"/tmp/test1","aa","IN_CREATE"
Sat Dec 5 17:28:29 JST 2009,"/tmp/test1","aa","IN_OPEN"
Sat Dec 5 17:33:00 JST 2009,"/tmp/test1","","IN_OPEN,IN_ISDIR"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swpx","IN_CLOSE_WRITE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1","","IN_OPEN,IN_ISDIR"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1","","IN_CLOSE_NOWRITE,IN_ISDIR"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swpx","IN_OPEN"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_CLOSE_WRITE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swpx","IN_CREATE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1","","IN_CLOSE_NOWRITE,IN_ISDIR"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_DELETE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_MODIFY"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_CREATE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swpx","IN_DELETE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1","","IN_CLOSE_NOWRITE,IN_ISDIR"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_CREATE"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_OPEN"
Sat Dec 5 17:33:04 JST 2009,"/tmp/test1",".bb.swp","IN_OPEN"
Sat Dec 5 17:33:06 JST 2009,"/tmp/test1",".bb.swp","IN_MODIFY"
Sat Dec 5 17:33:13 JST 2009,"/tmp/test1","bb","IN_CREATE"
Sat Dec 5 17:33:13 JST 2009,"/tmp/test1","bb","IN_OPEN"
Sat Dec 5 17:33:13 JST 2009,"/tmp/test1","bb","IN_CLOSE_WRITE"
Sat Dec 5 17:33:49 JST 2009,"/tmp/test1","cc","IN_MOVED_TO"
実行のログについては通常のcronと同様に/var/log/cronに残される。
/var/log/cron
Dec 5 17:26:29 sailane incrond[13481]: table for user hsur changed, reloading
Dec 5 17:27:58 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_OPEN,IN_ISDIR")
Dec 5 17:27:59 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_OPEN,IN_ISDIR")
Dec 5 17:27:59 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_CLOSE_NOWRITE,IN_ISDIR")
Dec 5 17:28:29 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "aa" "IN_CREATE")
Dec 5 17:28:29 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "aa" "IN_OPEN")
Dec 5 17:33:00 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_OPEN,IN_ISDIR")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_OPEN,IN_ISDIR")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "" "IN_CLOSE_NOWRITE,IN_ISDIR")
Dec 5 17:33:04 sailane last message repeated 2 times
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_CREATE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_OPEN")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swpx" "IN_CREATE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swpx" "IN_OPEN")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swpx" "IN_CLOSE_WRITE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swpx" "IN_DELETE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_CLOSE_WRITE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_DELETE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_CREATE")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_OPEN")
Dec 5 17:33:04 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_MODIFY")
Dec 5 17:33:06 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" ".bb.swp" "IN_MODIFY")
Dec 5 17:33:13 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "bb" "IN_CREATE")
Dec 5 17:33:13 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "bb" "IN_OPEN")
Dec 5 17:33:13 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "bb" "IN_CLOSE_WRITE")
Dec 5 17:33:49 sailane incrond[13481]: (hsur) CMD (/tmp/test1.sh "/tmp/test1" "cc" "IN_MOVED_TO")