使用Apache Commons CLI开发命令行工具

工作两年多,从没遇到需要使用命令行那样的参数形式执行命令的需求,突然好奇想试试,于是找到了Apache Commons CLI,大致了解试用了下,挺简单的,总共也就那点东西。
Apache Commons CLI官网地址:(https://commons.apache.org/cli/download_cli.cgi)
使用Apache Commons CLI开发命令行工具分成三步:
1)定义CLI
2)解析CLI
3)处理CLI
首先我们参考官网给出的一个例子:

ant [options] [target [target2 [target3] ...]]
  Options: 
  -help                  print this message
  -projecthelp           print project help information
  -version               print the version information and exit
  -quiet                 be extra quiet
  -verbose               be extra verbose
  -debug                 print debugging information
  -emacs                 produce logging information without adornments
  -logfile <file>        use given file for log
  -logger <classname>    the class which is to perform logging
  -listener <classname>  add an instance of class as a project listener
  -buildfile <file>      use given buildfile
  -D<property>=<value>   use value for given property
  -find <file>           search for buildfile towards the root of the
                         filesystem and use it

该例子是ant的命令,我们可以对照着进行开发(其实官网就有,英文好的可以直接移步
(https://commons.apache.org/proper/commons-cli/usage.html))。

定义CLI:

首先参照上面的三部曲,第一步定义CLI:
Apache Commons CLI使用Option表示每一个命令,使用Options封装多个Option,创建Option的方式有三种:

  1. Option op = new Option(…);//构造器
  2. Options.addOption(…);//Options直接构造
  3. Option.Builder辅助类
    1.2适合简单的创建的命令,如上面logfile命令以上的命令。我们举几个例子:
Options ops = new Options();
Option help = new Option( "help", "print this message" );
ops.addOption(help);
ops.addOption("projecthelp", "print project help information");

同时如果我们假设debug命令后可跟值true/false,那么我们可以这样定义命令:

ops.addOption("debug", true, "print debugging information"); //第二个参数true表示该命令后可跟参数,其实就是命令后面跟上值

下面我们看logfile以下除去-D<property>=<value> 之外的的命令如何创建,这里使用第三种方式:

Option logfile = Option.builder("logfile").argName("file").hasArg().desc("use given file for log").build();// argName指定命令后跟的参数名称
ops.addOption(logfile);

最后我们看看如何定义-D<property>=<value>

Option D = Option.builder("D").argName("property=value").numberOfArgs(2).valueSeparator("=")
                .desc("use value for given property").build();// 这里numberOfArgs指定了后跟两个参数,且valueSeparator指定了连接符是=,这样CLI可以自动帮我们解析键值对
ops.addOption(D);
解析CLI:

以上全部定义好之后,就可以对传入的参数进行解析了。DefaultParser类是用来解析参数,得到每个命令以及对应的值,而且对于如上面的-D<property>=<value> 这种命令,由于我们制定了“=”为分隔符,DefaultParser可以自动为我们将参数解析成Properties,很方便。

CommandLine comm = null;
try {
    comm = new DefaultParser().parse(ops, args);
} catch (ParseException e) {
    e.printStackTrace();
    log.error("解析参数失败,参数:[" + Arrays.asList(args).toString() + "]");
    throw new IllegalArgumentException();
}
处理CLI

上面已经对传入的参数解析好了,剩下的就是获取到这些命令的值,以及进行相应的处理了,也就是我们的业务逻辑了。

if (comm.getOptions().length == 0) {
    log.info("No any param to specify.");
    return;
}
if (comm.hasOption("h")) {// help
    HelpFormatter formatter = new HelpFormatter();
    formatter.printHelp("options", ops);
}
if (comm.hasOption("s")) {// 执行命令
    new SystemCommand().execute(comm.getOptionValue("s"));
}
if (comm.hasOption("D")) {// 传递参数
    Properties props = comm.getOptionProperties("D");
    new ParamParser(props).parse();
}

上面是一个简单的例子,这里有个getOptionProperties方法,这个方法是针对使用分隔符的命令方便获取键值对行为的属性值而设计的,很好用,免去了自己再做字符串切分的麻烦。
到这里整个使用Apache Commons CLI开发命令行工具的工作就完成了,很简单。

  • Apache Commons CLI总共支持的几种命令模式:
  • POSIX like options (ie. tar -zxvf foo.tar.gz)
  • GNU like long options (ie. du –human-readable –max-depth=1)
  • Java like properties (ie. java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo)
  • Short options with value attached (ie. gcc -O2 foo.c)
  • long options with single hyphen (ie. ant -projecthelp)
    对于GNU模式官网还有一个例子,可以自行参考下。
    附上官网的一个Option的属性表:
NameTypeDescription
optjava.lang.Stringthe identification string of the Option.
longOptjava.lang.Stringan alias and more descriptive identification string.
descriptionjava.lang.Stringa description of the function of the option.
requiredbooleana flag to say whether the option must appear on the command line.
argbooleana flag to say whether the option takes an argument.
argsbooleana flag to say whether the option takes more than one argument.
optionalArgbooleana flag to say whether the option’s argument is optional.
argNamejava.lang.Stringthe name of the argument value for the usage statement.
valueSeparatorcharthe character value used to split the argument string, that is used in conjunction with multipleArgs e.g. if the separator is ‘,’ and the argument string is ‘a,b,c’ then there are three argument values, ‘a’, ‘b’ and ‘c’.
typejava.lang.Objectthe type of the argument.
valuejava.lang.Stringthe value of the option.
valuesjava.lang.String[]the values of the option.

参考文章:
使用 Apache Commons CLI 开发命令行工具
Apache Commons CLI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值