JSONを使ってコマンドラインを動的に組み立てて実行するjfillを作った
https://github.com/Songmu/jfill
標準入力からJSONを受け取り、その値を使ってコマンドラインを組み立てて実行するユーティリティです。以下のような具合です。
インストール
% go get github.com/Songmu/jfill/cmd/jfill
もしくはGitHub Releasesからご利用ください。
使い方
% echo '{"name":"jfill"}' | jfill echo Hello {{name}}!
Hello jfill!
{{name}}
の部分がプレースホルダーです。それがJSONの入力を元に置換され実行されています。
プレースホルダー内には以下のようにデフォルト値を指定することも可能です。
% echo '{}' | jfill echo Hello {{name:jfill}}!
Hello jfill!
{{name:jfill}}
のコロン以降の"jfill"の部分がデフォルト値です。プレースホルダーにデフォルト値が指定されておらず、置換対象のキーがJSON内に存在しない場合、jfill
は失敗します。
深い構造のJSONに対応するために、プレースホルダー内にXPathのような文字列を指定することができます。内部的には github.com/mattn/go-scan
を利用しています。
% echo '{"Songmu":{"age":38}}' | jfill echo Songmu is {{/Songmu/age}} years old.
Songmu is 38 years old.
作った動機
主にMackerelのチェック監視で、引数を動的に指定させる仕組みが欲しかったのが動機。何らかのパラメーターストアとjfill
と連携させれば動的に引数を指定できます。以下はmackerel-agent.confのサンプル。
[plugin.checks.unicorn-worker]
command = '''
echo '{"threshold":'$(getconf _NPROCESSORS_ONLN)'}' \
| jfill check-procs -P unicorn --critical-under={{threshold:5}}
'''
少しわざとらしい例ですが、この場合、CPUコア数よりもワーカー数が少なくなった時にアラートが上がります。JSONが正しく出力できなかったときにエラーになるのを防ぐためにデフォルト値を指定するのが推奨です。
ConsulのKVSやMackerelのmetadata APIと組み合わせるのも賢い方法です。ちなみにMackerelのmetadata APIを利用する際に毎分アクセスするのは効率が悪いため、何らかのキャッシュ機構を使うことを強く推奨します。(お願いします…!
環境変数を動的にセットしたい場合
env
コマンドと組み合わせると良いでしょう。
% echo '{"lang":"ja_JP.UTF-8"}' | jfill env LANG={{lang}} date
2018年 6月12日 火曜日 01時27分28秒 JST
fillinとの違い
https://github.com/itchyny/fillin というものがありまして、僕も便利に使っているのですが、ユースケースが違うため、別で作ることにしました。
まとめ
ぜひご利用ください!仕組み上、結構危ないことができてしまうため、ご利用は計画的に!