monoの開発ブログ

fswatch が便利で面白い

(Updated on )

つい最近まで手動で gtags を叩いていたのですが、2015年にもなってさすがにそれはないだろうと思い、自動でやってくれるようにしてみました。今回自動化のために採用したのは、タイトルにもある fswatch というツールです。

fswatch を使うと、以下のような簡単なコマンドでファイルが更新されたときに自動で gtags を叩くことができます。

fswatch -r bin lib view | xargs -n1 -I{} gtags -iv

便利。そして、なかなか渋くて面白いコマンドの並びですよね。まさかこんなところで find 以外の使い道がわからない xargs にお目にかかるとは。

実は、fswatch は指定されたディレクトリ内の変更を監視して変更があるとそのファイルのパスを標準出力に出力するだけで、それ以上のことは何もしてくれません。そこで登場するのがあの xargs です。xargs は、標準入力を引数として指定したコマンドを実行してくれるコマンドです。通常はコマンドを実行するタイミングは xargs が良きに計らってくれるので、実際にコマンドがいつ何回実行されているかを意識することは無いと思いますが、-n1 を付けた場合には標準入力が1行入ってくるたびに必ずコマンドを実行するようになります。これにより、標準入力をトリガとしてコマンドを実行できます。

もう1つの -I{} オプションは、標準入力を空文字列に置換して渡すという意味です。今回は、標準入力を引数として渡してくれる機能は無効化して、標準入力をトリガにコマンドを実行する機能だけを活用しているわけですね。

つまり、最初に載せたコマンドは、fswatch がディレクトリ内のファイルを検知して標準出力にパスを出力するたびに、xargs が gtags -iv を実行してくれるというわけです。久しぶりに UNIX 的な面白いコマンドの使い方に出会えた気がしました。

追記 2016-01-22

上のコマンドだとファイルが1つ変更されるごとに1回 gtags が起動するようになっていたため、git checkout のように一度に大量のファイルが変更されるようなことがあると無駄に何度も gtags が起動するようになっていました。しかし、gtags の場合には、複数あるファイルのうちどれかが変更されたら1回コマンドが実行されれば十分です。

そういった場合には -o オプションと -l オプションが使えます。-o オプションは -l オプションで指定した秒数の間に変更されたファイルの数を標準出力に書き出すという動きをしてくれるので、短時間の間に大量のファイルが変更されても出力は1行だけになり、xargs と組み合わせて使うのに好都合です。

fswatch -r -o -l 3 bin lib view | xargs -n1 -I{} gtags -iv