ruby でファイル書き換わった時に処理をしたいと思ったので。ファイルの監視とイベントといえば inotify なので、rb-inotify を使ってみた
require 'rb-inotify' path_a = "/home/takuya/test/FileA" path_b = "/home/takuya/test/FileB" path_list = [ "/home/takuya/test/linkA", path_a, path_b, ] notifier = INotify::Notifier.new path_list.each{|e| notifier.watch(e, :all_events,:dont_follow) do |ev| puts "#{e} was #{ev.flags}." $stdout.flush $stdout.sync end } notifier.run
実行してみた
ファイルに何かが起きると、それぞれ対応したイベントが起きる。イベントの種類は、inotify に準じるの。
慣れないので、どのイベントが起きるのが上手く把握できないので、:all_events と、リンクを辿らない:dont_follow をツケて試した。
## ファイルに対する処理 takuya@atom:~/test$ echo aa > FileA takuya@atom:~/test$ touch linkA takuya@atom:~/test$ unlink linkA takuya@atom:~/test$ ln -s FileA linkA ## 起こったイベントたち takuya@atom:~$ ruby softcas_checker.rb /home/takuya/test/FileA was [:modify]. /home/takuya/test/FileA was [:open]. /home/takuya/test/FileA was [:modify]. /home/takuya/test/FileA was [:close_write, :close]. /home/takuya/test/FileA was [:open]. /home/takuya/test/FileA was [:attrib]. /home/takuya/test/FileA was [:close_write, :close]. /home/takuya/test/linkA was [:attrib]. /home/takuya/test/linkA was [:delete_self]. /home/takuya/test/linkA was [:ignored].
イベントでナニが起きたかは、Event#flags で取得することが出来る。
notifier.watch(e, :all_events,:dont_follow) { |ev| puts "#{e} was #{ev.flags}." }
これで、どのイベントがどの操作で発生するかがわかる。
notifier は削除後の監視は出来ない
inotify は i-node なので 削除するとi-node が変わるので、変化を追えなくなるようでした。
今回は、ウッカリファイルが削除どうするかってことなので、
ファイルがどこかにmoveされたり、unlinkされた場合のイベント処理は
- ディレクトリで監視する
- ファイルが消えたら→再度inotify を仕込むか
で仕掛けておかないと継続しないですね。