shell スクリプトと Ruby スクリプトで設定を共有する
あらためて書くほどたいした話じゃないです。
細々した仕事をするスクリプトの多くは基本的に sh スクリプトが多いと思うのですが、やはり sh スクリプトでは多少荷が重い仕事もあります。awk や sed などを使うのはまぁ常套手段ではありますが、あんまり激しくコマンドを呼び出すとそれだけ負荷が高くなっていきます。そういう場合、自分は Ruby で書き直してしまうのですが、すでに稼働中の sh スクリプトを含めて毎回同じような設定を書いていることに気がつきました。わずか数行の代入文とは言え、なんかこれ無駄な感じがします。
sh スクリプトの変数代入は基本的に以下のように書きます。
VAR=VAL
自分の場合、sh スクリプトの変数は常に大文字で書くようにしているのですが、よく見たらコレ、
Ruby の定数定義と同じじゃん
と気づきました。しかも Ruby はバッククォートを使った別プロセスの結果の取得も sh スクリプトと同じように動きます。つまり、特別なフォーマット(XML やら YAML やら)を用意しなくても、特別なパーサを用意しなくても、同じ設定をそのまま sh でも Ruby でも読み込むことができるということです。
具体的にやることは以下のように、
- 変数定義の部分を別ファイルに切り出し
- sh スクリプトでは . で 1 のファイルを読み込む
- Ruby スクリプトでは load で 1 のファイルを読み込む
だけです。
Ruby の方で定数はちょっと扱いにくいなぁと思ったら Object.const_defined?(), Object.const_get() を使って変数に取り込むことも可能です。
最初から小文字で変数を書いて Ruby でもローカル変数として取り込めばいいじゃんという意見もあるかもしれませんけど、Ruby スクリプト側は恐らくコードと設定の分離を意識して書きたいだろうから、ローカル変数にいきなり取り込むよりいったん定数で取り込んでおいて、それを必要に応じて使えるようにしておいた方が気持ちいいような気がします。で、この処理を module に追い出してしまえば毎回書く必要もありません。うん、いいアイディアだ。