BLOGTIMES
2011/09/02

Commons CLI でコマンドラインオプションをパースする

  java  cli 
このエントリーをはてなブックマークに追加

自作のCLIアプリのオプションをパースする必要がでてきたので、Rubyのoptparseのようなものが確かJavaにもあったはずということで、調べてみたら意外と種類が一杯あったので、とりあえず有名どころのものをいくつか触ってみることにしました。

手始めにApache Commons の CLI というライブラリ。

Commons CLI - Home

The Apache Commons CLI library provides an API for parsing command line options passed to programs. It's also able to print help messages detailing the options available for a command line tool.

以下、作業メモ。

対象とするオプション

今回はこんなコマンドをとるコマンドを想定してみます。

-a aaa [-b] [-c ccc] [-d [ddd]] eee.txt

標準のヘルプ生成を使うとこんな感じのヘルプが生成されるようです。

$ java -jar CommonsCLIExample.jar -a aaa -h usage: CommonsCLIExample -a [-b] [-c <arg>] [-d <arg>] [-h] -a -b -c <arg> -d <arg> -h

ちなみにいろいろな引数を与えてテストしてみた結果はこちら。

$ java -jar CommonsCLIExample.jar -a aaa -- eee.txt -a, a = aaa, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -- eee.txt -a, a = aaa, -b, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -c ccc -- eee.txt -a, a = aaa, -b, c, c = ccc, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -c ccc -d -- eee.txt -a, a = aaa, -b, c, c = ccc, -d, d = --, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -c ccc -d dnew -- eee.txt -a, a = aaa, -b, c, c = ccc, -d, d = dnew, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar eee.txt org.apache.commons.cli.MissingOptionException: Missing required option: a at org.apache.commons.cli.Parser.checkRequiredOptions(Parser.java:299) at org.apache.commons.cli.Parser.parse(Parser.java:231) at org.apache.commons.cli.Parser.parse(Parser.java:85) at CommonsCLIJOptSimpleExample.main(CommonsCLIJOptSimpleExample.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
$ java -jar CommonsCLIExample.jar -a aaa fff -- eee.txt -a, a = aaa, d = ddd, 残りのパラメータ -> fff, eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b bbb -- eee.txt -a, a = aaa, -b, d = ddd, 残りのパラメータ -> bbb, eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -c -- eee.txt -a, a = aaa, -b, c, c = --, d = ddd, 残りのパラメータ -> eee.txt,
$ java -jar CommonsCLIExample.jar -a aaa -b -c -d -- eee.txt org.apache.commons.cli.MissingArgumentException: Missing argument for option: c at org.apache.commons.cli.Parser.processArgs(Parser.java:343) at org.apache.commons.cli.Parser.processOption(Parser.java:393) at org.apache.commons.cli.Parser.parse(Parser.java:199) at org.apache.commons.cli.Parser.parse(Parser.java:85) at CommonsCLIJOptSimpleExample.main(CommonsCLIJOptSimpleExample.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
$ java -jar CommonsCLIExample.jar -a aaa -b -d dnew ggg -- eee.txt -a, a = aaa, -b, -d, d = dnew, 残りのパラメータ -> ggg, eee.txt,

エラーになっているのは、必須のオプションが指定されていないときと、オプションの引数が足りないときですね。

サンプルコード

CommonsCLIExample.java

import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; public class CommonsCLIExample { public static void main(String[] args){ Options options = new Options(); // -a の定義 OptionBuilder.isRequired(); OptionBuilder.hasArgs(1); options.addOption(OptionBuilder.create('a')); // -b の定義 OptionBuilder.hasArgs(0); options.addOption(OptionBuilder.create('b')); // -c の定義 OptionBuilder.hasArgs(1); options.addOption(OptionBuilder.create('c')); // -d の定義 OptionBuilder.hasArgs(); OptionBuilder.hasOptionalArgs(1); options.addOption(OptionBuilder.create('d')); // help の定義 options.addOption(OptionBuilder.create('h')); // argsのパース CommandLineParser parser = new PosixParser(); CommandLine cl = null; try { cl = parser.parse(options, args); } catch (ParseException e) { e.printStackTrace(); System.exit(-1); } // 取得結果の処理 if( cl.hasOption("h") ){ HelpFormatter help = new HelpFormatter(); help.printHelp(CommonsCLIExample.class.getName(), options, true); } if( cl.hasOption("a") ){ System.out.print("-a, "); System.out.print("a = "+ cl.getOptionValue("a")+", "); } if( cl.hasOption("b") ){ System.out.print("-b, "); } if( cl.hasOption("c") ){ System.out.print("c, "); System.out.print("c = "+ cl.getOptionValue("c")+", "); } if( cl.hasOption("d") ){ System.out.print("-d, "); } System.out.print("d = "+ cl.getOptionValue("d","ddd")+", "); System.out.print("残りのパラメータ -> "); for( String s : cl.getArgs()){ System.out.print(s+", "); } } }

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/4423
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン