概要
Rubyで手軽に
<script> <sub-command> [options...]
というような書式のLinux/Unixコマンドラインプログラムを作る方法を覚え書きします。
ちなみに、NWテスト用ツールの作成の過程で検討・採用した方法です。
同ツール群もご覧いただければ幸いです。
https://github.com/YohKmb/nwutils
流れ
当記事では、以下の処理について記載します。
1. ARGVの冒頭引数の摘出
2. optparseモジュールの略式オプション解釈を利用
3. サブコマンド毎の必須オプションに不足がないかの検証
1. ARGVの冒頭引数の摘出
これ以降は、下記のURLのプログラムを例にとって、上で列挙した「流れ」について、順に説明します。
https://github.com/YohKmb/nwutils/blob/master/multiping/multping
まず、プログラムで採用するサブコマンドと、それぞれの必須オプションをHash定数として定義します。
SUBCMDS = {"add" => "va", "del" => "", "ping" => "tl", "help" => ""}
次に、プログラム引数配列ARGVから冒頭の要素を取り出してサブコマンドとして扱います。
cmd = ARGV.shift
2. optparseモジュールの略式オプション解釈を利用
次いで、残りの引数をオプション引数として解釈します。
require "optparse"
# (・・・中略・・・)
params = ARGV.getopts("v:b:a:t:x:g:s:l:Th", "l3", "no-log", "help")
サブコマンドと引数が得られたこの時点で、helpの表示の必要有無を判断しても良いでしょう。
def _help(exit_status)
print USAGE
exit(exit_status)
end
# (・・・中略・・・)
_help(0) if cmd == "help" or cmd == "-h" or params["h"] or params["help"]
3. サブコマンド毎の必須オプションに不足がないかの検証
最初に定義した{<サブコマンド> : <必須オプション>}
のマッピングのHash定数を利用して、オプション検証を行います。
なお、デフォルト値によるパラメータ初期化は、これに先んじて実施すると良いと思います。
def _validate_opts(params, subcmd)
musts = SUBCMDS[subcmd]
res = musts != "" ?
musts.each_char.map do |must| not params[must].nil? end :
[true]
if not res.all?
puts "Error : Some needed parameter are ignored"
puts
_help(1)
end
end
# (・・・中略・・・)
if !SUBCMDS.keys.include?(cmd)
puts "Error : Invalid subcommand"
puts
_help(1)
end
_validate_opts(params, cmd)
余談
普段、RubyよりもPythonに慣れているため、当方のソースコードにはRubyistの方から見れば至らないコーディングもあるかと存じます。
ただ、誰かしらお困りの方の参考になれば幸いです。