それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ruby で inotify を使ってみた。

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された場合のイベント処理は

  1. ディレクトリで監視する
  2. ファイルが消えたら→再度inotify を仕込むか

で仕掛けておかないと継続しないですね。