ご無沙汰しております。
tl;dr
自分の中で以下のブームが到来しております。
- ディレクトリ監視(ファイル作成、削除、編集等のイベント検知)
- ツールは出来るだけワンバイナリで提供したい(でも Go 言語は Hello world 準一級 = 初心者)
これからのブームを満たしてくれるのが mruby そして mruby-cli ということで、mruby 界に名を轟かすべくサンプルツールを作ってみることにしました。
リンク
参考
- https://github.com/hone/mruby-cli
- https://github.com/matsumoto-r/pfds
- https://github.com/harasou/gfmarkdown
- https://github.com/FlavourSys/mruby-inotify
- https://github.com/mttech/mruby-getopts
- http://harasou.github.io/2015/12/20/gfmarkdown-release/
- http://hb.matsumoto-r.jp/entry/2015/10/23/133753
作ったもの
どんなものか
ダウンロードしてすぐ使える
もし、気になった方がいらっしゃったらこちらからダウンロードしてみて下さい。
ひとまずヘルプ
$ ./watcher --help Usage: watcher [options] -h, --help Display help. -v, --version Display version. --path WATCH_PATH Set monitoring directory path.
デモ
watcher バイナリを適当なパスにダウンロードするだけ。上のウィンドウで展開している test_dir
を監視するように watcher を実行している図。
watcher を支える技術(というほどでもないけど)
ディレクトリ変更検知
- ディレクトリ変更検知には mruby-inotify を利用
# # サンプルをほぼそのまま流用 # def watch logging('DEBUG', 'Watch starting...') watcher = Inotify::RecursiveNotifier.new watcher.rwatch(@path, :all_events) do |event| # puts event.inspect # # - [close_write, :close] # - 書き込みが発生したファイルを検知する # if event.events[0] == :close_write && event.events[1] == :close if event.watched_path[-1] == '/' logging('INFO', event.watched_path + event.name) else logging('INFO', event.watched_path + '/' + event.name) end end end
:all_events
以外のイベント :create
を利用すると Segmentation fault (core dumped)
を吐いてアプリケーションが落ちてしまう(こちらの原因調査に時間を要した...)ので、all_events
を利用して、ファイルの書き込みが完了した(と思われる)イベントの close_write, :close
を利用しました。
Watcher クラスを呼び出す処理
- Watcher クラスを呼び出す処理
def __main__(argv) opt = Getopts.getopts( 'vh', 'version', 'help', 'path:' ) if opt['v'] || opt['version'] puts "v#{Watcher::VERSION}" elsif opt['h'] || opt['help'] || opt['path'] == '' puts "#{Watcher::HELP}" elsif opt['path'] w = Watcher::Watcher.new(opt) w.watch else puts "#{Watcher::HELP}" end end
こちらを参考にさせて頂いて、引数の処理には mruby-getopts を利用しました。
ワンバイナリ提供が必要なら mruby + mruby-cli の利用も検討したい
mruby-cli でワンバイナリツールの作り方については...
以下の記事がとても Blog 記事が参考になりました。
一回読めば、mruby-cli のツール作りの基本を理解することが出来ます。有難うございました。
実は Windows 版のバイナリを作りたかったんですが...
Windows 上でも動かしてみたいと考えて、Ubuntu 14.04 上で Windows 向けのバイナリを生成しようとしましたが...以下のようなエラーが...
... /watcher/mruby/build/mrbgems/mruby-inotify/src/inotify.c:8:25: fatal error: sys/inotify.h: No such file or directory #include <sys/inotify.h> ^ compilation terminated. ... /watcher/mruby/build/mrbgems/mruby-inotify/src/inotify.c:8:25: fatal error: sys/inotify.h: No such file or directory #include <sys/inotify.h> ^ compilation terminated. rake aborted!
ちくしょー、ちくしょー。きっと、必要なライブラリが揃ってないだけなんだ、そうなんだ...。ん、Windows で inotify が動くのかとかそのレベルなのかもしれない。
とは言え...
mruby と mruby-cli を使えば Ruby DSL を使って異なる環境のワンバイナリツールを書けるというのは個人的にとてもうれしい限りです。Go 言語同様に Ruby や mruby に関しても初心者の域を出ておりませんが、Go 言語と比較すると若干慣れ親しんでいるという点で個人的には推していきたいなと考えております。
以上。