LoginSignup
5
6

More than 5 years have passed since last update.

Rubyで手軽にサブコマンド + オプションを実装

Last updated at Posted at 2015-05-16

概要

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の方から見れば至らないコーディングもあるかと存じます。

ただ、誰かしらお困りの方の参考になれば幸いです。

5
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6