Apache Commons CLI官方文档翻译 —— 快速构建命令行启动模式
昨天通过几个小程序以及Hangout源码学习了CLI的基本使用,今天就来尝试翻译一下CLI的官方使用手册。
下面将会通过几个部分简单的介绍CLI在应用中的使用场景。
昨天已经联系过几个基本的命令行参数使用场景,可以参考这里
通过使用Apache Commons CLI可以帮助开发者快速构建命令行启动模式,并可以快速生成帮助指令,基于用户启动参数提供不同的服务。
入门样例
下面就举个例子,比如我想输入命令:
xxx -t
从而打印出当前的时间。
定义阶段——创建选项
首先要创建Options对象,然后添加Option对象.
// create Options object
Options options = new Options();
// add t option
options.addOption("t", false, "display current time");
其中addOption方法有三个参数:
- 第一个参数是字符串类型,代表命令的参数。
- 第二个参数是Bool型,代表该选项是否需要额外的参数。
- 第三个参数是该选项的描述信息。
上面的例子就代表,t选项不需要参数,它的意思是显示当前时间。
解析阶段——解析命令行参数
CLI通过CommandLineParser的parse方法解析命令行参数。有好几种CommandLineParser的实现类,推荐使用的是DefaultParser。看源码除了这个DefaultParser,其他的都被打上了@Deprecated标记。
除去这个DefaultParser以外,还有一个抽象类实现了CommandLineParser接口——Parser,这个Parser有三个子类:
- BasicParser
- GnuParser
- PosixParser
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
询问阶段—— 判断命令行中出现了哪个选项
现在就可以检查是否存在这个t选项了,首先需要在CommandLine对象中进行查询。hasOption方法可以通过选项的名字,判断命令行是否出现该命令。出现则返回true,否则返回false。
if(cmd.hasOption("t")) {
// print the date and time
}
else {
// print the date
}
全部代码
public class DateApp {
public static void main(String[] args) {
String[] arg = {"-t"};
// String[] arg = {};
try {
testOption(arg);
} catch (ParseException e) {
e.printStackTrace();
}
}
static void testOption(String[] args) throws ParseException{
Options options = new Options();
options.addOption("t", false, "display current time");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("t")) {
System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
}else {
System.out.println((new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
}
}
}
进阶样例
下面这个例子继承自DateApp,并且提供了根据城市显示时间和日期的功能。为了实现这个命令,会增加一个c选项,来添加城市信息。
// add c option
options.addOption("c", true, "country code");
第二个参数这时设置为true,就代表它需要额外的参数。
获得参数值
CommandLine对象的getOptionValue方法可以获取到参数的值。
// get c option value
String countryCode = cmd.getOptionValue("c");
if(countryCode == null) {
// print default date
}else {
// print date for country specified by countryCode
}
此时如果只有c选项,没有参数,就会报错
org.apache.commons.cli.MissingArgumentException: Missing argument for option: c
at org.apache.commons.cli.DefaultParser.checkRequiredArgs(DefaultParser.java:211)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:125)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:76)
at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:60)
at hangout.study.InternationalDateApp.testOption(InternationalDateApp.java:29)
at hangout.study.InternationalDateApp.main(InternationalDateApp.java:18)
全部代码
public class InternationalDateApp {
public static void main(String[] args) {
String[] arg = {"-t","-c","hello"};
// String[] arg = {"-t","-c"};
// String[] arg = {};
try {
testOption(arg);
} catch (ParseException e) {
e.printStackTrace();
}
}
static void testOption(String[] args) throws ParseException{
Options options = new Options();
options.addOption("t", false, "display current time");
options.addOption("c", true, "country code");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("t")) {
System.out.println((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())+" in "+cmd.getOptionValue("c"));
}else {
System.out.println((new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
}
}
}
此时运行代码,则会正确输出信息:
2016-06-23 21:18:50 in hello
Ant样例
下面举一个Ant的样例,下面是Ant输出的帮助信息
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
使用Bool选项创建
Option help = new Option( "help", "print this message" );
Option projecthelp = new Option( "projecthelp", "print project help information" );
Option version = new Option( "version", "print the version information and exit" );
Option quiet = new Option( "quiet", "be extra quiet" );
Option verbose = new Option( "verbose", "be extra verbose" );
Option debug = new Option( "debug", "print debugging information" );
Option emacs = new Option( "emacs","produce logging information without adornments" );
也可以使用OptionBuilder构建选项:
Option logfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given file for log" )
.create( "logfile" );
Option logger = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "the class which it to perform "+ "logging" )
.create( "logger" );
Option listener = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "add an instance of class as "+ "a project listener" )
.create( "listener");
Option buildfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given buildfile" )
.create( "buildfile");
Option find = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "search for buildfile towards the "+ "root of the filesystem and use it" )
.create( "find" );
最后一个OptionBuilder创建带有参数名称的选项:
Option property = OptionBuilder.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription( "use value for given property" )
.create( "D" );
通过上面的方式定义的属性,可以通过CommandLine对象的getOptionProperties("D")方法获得。
定义阶段——创建选项
Options options = new Options();
options.addOption( help );
options.addOption( projecthelp );
options.addOption( version );
options.addOption( quiet );
options.addOption( verbose );
options.addOption( debug );
options.addOption( emacs );
options.addOption( logfile );
options.addOption( logger );
options.addOption( listener );
options.addOption( buildfile );
options.addOption( find );
options.addOption( property );
解析阶段——创建解析器
跟前面类似,创建CommandLineParser解析器,返回CommandLine对象,用于查询选项参数。
public static void main( String[] args ) {
// create the parser
CommandLineParser parser = new DefaultParser();
try {
// parse the command line arguments
CommandLine line = parser.parse( options, args );
}
catch( ParseException exp ) {
// oops, something went wrong
System.err.println( "Parsing failed. Reason: " + exp.getMessage() );
}
}
询问阶段——查询命令行参数
通过hasOption选项判断是否包含某个选项参数:
// has the buildfile argument been passed?
if( line.hasOption( "buildfile" ) ) {
// initialise the member variable
this.buildfile = line.getOptionValue( "buildfile" );
}
创建帮助信息
一般命令行工具都有help帮助提示,即输入-h命令,就会输出所有的命令参数。CLI提供给我们快捷输出帮助信息的工具——HelpFormatter。
// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "ant", options );
当执行到此处时,就会输出相应的帮助信息
usage: ant
-D <property=value> use value for given property
-buildfile <file> use given buildfile
-debug print debugging information
-emacs produce logging information without adornments
-file <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
全部代码
public class AntExample {
public static void main(String[] args) {
String[] arg = {"-help"};
testOption(arg);
}
@SuppressWarnings({ "deprecation", "static-access" })
static void testOption(String[] args){
Option help = new Option( "help", "print this message" );
Option projecthelp = new Option( "projecthelp", "print project help information" );
Option version = new Option( "version", "print the version information and exit" );
Option quiet = new Option( "quiet", "be extra quiet" );
Option verbose = new Option( "verbose", "be extra verbose" );
Option debug = new Option( "debug", "print debugging information" );
Option emacs = new Option( "emacs","produce logging information without adornments" );
Option logfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given file for log" )
.create( "logfile" );
Option logger = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "the class which it to perform "+ "logging" )
.create( "logger" );
Option listener = OptionBuilder.withArgName( "classname" )
.hasArg()
.withDescription( "add an instance of class as "+ "a project listener" )
.create( "listener");
Option buildfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given buildfile" )
.create( "buildfile");
Option find = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "search for buildfile towards the " + "root of the filesystem and use it" )
.create( "find" );
Option property = OptionBuilder.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription( "use value for given property" )
.create( "D" );
Options options = new Options();
options.addOption( help );
options.addOption( projecthelp );
options.addOption( version );
options.addOption( quiet );
options.addOption( verbose );
options.addOption( debug );
options.addOption( emacs );
options.addOption( logfile );
options.addOption( logger );
options.addOption( listener );
options.addOption( buildfile );
options.addOption( find );
options.addOption( property );
CommandLineParser parser = new DefaultParser();
try {
CommandLine line = parser.parse( options, args );
if( line.hasOption( "buildfile" ) ) {
System.out.println(line.getOptionValue( "buildfile" ));
}
if( line.hasOption("help")){
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "ant", options );
}
}catch( ParseException exp ) {
System.err.println( "Parsing failed. Reason: " + exp.getMessage() );
}
}
}
运行后得到下面的输出信息:
usage: ant
-buildfile <file> use given buildfile
-D <property=value> use value for given property
-debug print debugging information
-emacs produce logging information without adornments
-find <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logfile <file> use given file for log
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
如果想在输出信息中加入参数列表,也可以在printHelp加入第三个参数true, formatter.printHelp( "ant", options, true);
usage: ant [-buildfile <file>] [-D <property=value>] [-debug] [-emacs]
[-find <file>] [-help] [-listener <classname>] [-logfile <file>]
[-logger <classname>] [-projecthelp] [-quiet] [-verbose] [-version]
-buildfile <file> use given buildfile
-D <property=value> use value for given property
-debug print debugging information
-emacs produce logging information without adornments
-find <file> search for buildfile towards the root of the
filesystem and use it
-help print this message
-listener <classname> add an instance of class as a project listener
-logfile <file> use given file for log
-logger <classname> the class which it to perform logging
-projecthelp print project help information
-quiet be extra quiet
-verbose be extra verbose
-version print the version information and exit
LS样例
这个例子模拟了Linux下的命令行使用帮助:
全部代码:
public class LSExample {
public static void main(String[] args) {
String[] arg = new String[]{ "--block-size=10" };
testOption(arg);
}
static void testOption(String[] args){
CommandLineParser parser = new DefaultParser();
// create the Options
Options options = new Options();
options.addOption( "a", "all", false, "do not hide entries starting with ." );
options.addOption( "A", "almost-all", false, "do not list implied . and .." );
options.addOption( "b", "escape", false, "print octal escapes for nongraphic "
+ "characters" );
options.addOption( OptionBuilder.withLongOpt( "block-size" )
.withDescription( "use SIZE-byte blocks" )
.hasArg()
.withArgName("SIZE")
.create() );
options.addOption( "B", "ignore-backups", false, "do not list implied entried "
+ "ending with ~");
options.addOption( "c", false, "with -lt: sort by, and show, ctime (time of last "
+ "modification of file status information) with "
+ "-l:show ctime and sort by name otherwise: sort "
+ "by ctime" );
options.addOption( "C", false, "list entries by columns" );
try {
CommandLine line = parser.parse( options, args );
if( line.hasOption( "block-size" ) ) {
System.out.println( line.getOptionValue( "block-size" ) );
}
}
catch( ParseException exp ) {
System.out.println( "Unexpected exception:" + exp.getMessage() );
}
}
}
输出可以得到下面的信息:
10
usage: ls
-a,--all do not hide entries starting with .
-A,--almost-all do not list implied . and ..
-b,--escape print octal escapes for nongraphic characters
-B,--ignore-backups do not list implied entried ending with ~
--block-size <SIZE> use SIZE-byte blocks
-c with -lt: sort by, and show, ctime (time of last
modification of file status information) with
-l:show ctime and sort by name otherwise: sort
by ctime
-C list entries by columns
参考
Apache Commons CLI官方文档翻译 —— 快速构建命令行启动模式的更多相关文章
- Go通过cobra快速构建命令行应用
来自jetbrains Go 语言现状调查报告 显示:在go开发者中使用go开发实用小程序的比例为31%仅次于web,go得益于跨平台.无依赖的特性,用来编写命令行或系统管理这类小程序非常不错. 本文 ...
- Apache Commons CLI 开发命令行工具示例
概念说明Apache Commons CLI 简介 虽然各种人机交互技术飞速发展,但最传统的命令行模式依然被广泛应用于各个领域:从编译代码到系统管理,命令行因其简洁高效而备受宠爱.各种工具和系统都 提 ...
- Apache Commons CLI命令行启动
今天又看了下Hangout的源码,一般来说一个开源项目有好几种启动方式--比如可以从命令行启动,也可以从web端启动.今天就看看如何设计命令行启动... Apache Commons CLI Apac ...
- 使用 Apache Commons CLI 开发命令行工具示例
Apache Commons CLI 简介 Apache Commons CLI 是 Apache 下面的一个解析命令行输入的工具包,该工具包还提供了自动生成输出帮助文档的功能. Apache Com ...
- 使用 Apache Commons CLI 解析命令行参数示例
很好的输入参数解析方法 ,转载记录下 转载在: https://www.cnblogs.com/onmyway20xx/p/7346709.html Apache Commons CLI 简介 Apa ...
- Apache Commons CLI 简介
CLI 命令代码实现 命令行程序处理流程相对比较简单,主要流程为设定命令行参数 -> 解析输入参数 -> 使用输入的数据进行逻辑处理CLI 定义阶段 每一条命令行都必须定义一组参数,它们被 ...
- The type org.apache.commons.cli.Options cannot be resolved. It is indirectly referenced from required .class files
在搭建好Hadoop Eclipse开发环境后,编写map-reduce,遇到如下的问题: 从字面上可以看出,工程缺少org.apache.commons.cli.Options,这个包被间接的被其他 ...
- PHP的CLI命令行运行模式浅析
在做开发的时候,我们不仅仅只是做各种网站或者接口,也经常需要写一些命令行脚本用来处理一些后端的事务.比如对数据进行处理统计等.当然也是为了效率着想,当一个事务有可能会有较长的耗时时,往往会交由服务器的 ...
- Spring Boot通过命令行启动发生FileNotFoundException
Spring Boot + Jersey 通过命令行启动会发生错误FileNotFoundException异常 异常信息如下: ERROR o.a.c.c.C.[Tomcat].[localhost ...
随机推荐
- 利用JS实现购物网站商品放大镜效果
大家几乎都有在网上购物的经验,有的网站会有一个商品放大镜功能, 就是把鼠标移到图片上的时候,旁边会有另外一张大的图片展示,等同于 放大镜效果,那这样的效果怎样实现的呢,我把代码发给大家,请大家参考. ...
- STL三种标准容器
顺序性容器 vector:从后面快速的插入与删除,直接访问任何元素 deque:从前面或后面快速的插入与删除,直接访问任何元素 list: 双链表,从任何地方快速的插入与删除 关联容器 set:快速查 ...
- 实战Java虚拟机之四:提升性能,禁用System.gc() ?
今天开始实战Java虚拟机之四:"禁用System.gc()". 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟 ...
- int(*f)(int)
int(*f)(int): 为指向函数的指针变量的定义方法,其中f为指向函数的指针变量,第一个int为函数返回值类型,第二个int为函数的形参类型.
- BZOJ 3365 Distance Statistics 点分治
这道题是一道点分治的题目,难度不大,可以拿来练手. 关键是对于找出来的重心的删除操作需要删掉这条边,这很重要. 还有每次找重心的时候,不但要考虑他的子节点的siz,还要考虑父节点的siz. 然后就A了 ...
- 【javaweb学习】解析XML
XML解析方式有两种 dom:Document Object Model文档对象模型,是w3c组织推荐的解析方式 sax:Simple Api XML不是官方标准,但它是XML社区实际上的标准,几乎所 ...
- 使用sql server 链接服务器
在我们的日常应用场景中经常会碰访问不同服务器上的数据库,即跨服务器访问操作不同的服务器上的SQL Sever数据库, 这个时候Sql Server的链接服务器就非常实用,创建SQL语句如下: --重新 ...
- 数据结构作业之用队列实现的基数排序(Java版)
题目: 利用队列实现对某一个数据序列的排序(采用基数排序),其中对数据序列的数据(第1和第2条进行说明)和队列的存储方式(第3条进行说明)有如下的要求: 1)当数据序列是整数类型的数据的时候,数据序列 ...
- Python之路【第十九章】:Django 数据库对象关系映射
Django ORM基本配置 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...
- Android 强烈推荐:程序员接私活那点事
今天周末在家宅着,并不是我不想运动,是因为北京的雨雪交加导致我想在家写文章,不过想想给大家写文章还是蛮惬意的,望一眼窗外,看一眼雪景,指尖在键盘上跳动,瞬间有种从屌丝程序员转变成了小姑娘们都羡慕的文艺 ...