使用
Apache Commons CLI 开发命令行工具
简介:虽然各种人机交互技术飞速发展,但最传统的命令行模式依然被广泛应用于各个领域:从编译代码到系统
管理,命令行因其简洁高效而备受宠爱。各种工具和系统都提供了详尽的使用手册,有些还提供示例说明如何二
次开发。然而关于如何开发一个易用、强壮的命令行工具的文章却很少。本文将结合
Apache Commons CLI,通
过一个完整的例子展示如何准备、开发、测试一个命令行工具。希望本文对有相关需求的读者能有所帮助。
基于
Apache Commons CLI 的命令行设计
通常情况下命令行处理有三个步骤:定义,解析和询问阶段。本章节将依次解释这三个步骤,并将结合实例来讨
论如何通过
Apache Commons CLI 来实现它们。由于本文作者一直从事和存储相关的工作,所以我们将设计一个
如何向
Server 中添加
/ 删除存储数据源的
CLI。
以下是具体应用场景,用户可以通过以下方式来添加
/删除通过
CIM (Common Information Model) Server 管理的存
储数据源:
1.添加通过
CIM Server 管理的存储,例如添加
IBM DS Series,命令行设计如下:
mkdatasource [-h | -? | --help]
mkdatasource [-t string] [-i string] [-p string] [-u string] [-w string] [-n string]
-h
Lists short help
-t
Sets the HTTP communication protocol for CIM connection
-i
Sets the IPv4 address of the device
-p
Sets the HTTP communication port for CIM connection
-u
Specifies the user ID for the data source connection
-w
Specifies the password for the data source connection
-n
Identifies the namespace of the CIM connection
Examples:
Add CIM Storage Subsystem
mkdatasource –t http –i 9.3.194.11 –p 5988 –u admin –w admin –n root/lsiarray13
2.删除通过
CIM Server 管理的存储,例如删除
IBM DS Series,命令行设计如下:
rmdatasource [-h | -? | --help]
rmdatasource [-t string] [-i string] [-p string]
-h
Lists short help
-t
Sets the HTTP communication protocol for CIM connection
-i
Sets the IPv4 address of the device
-p
Sets the HTTP communication port for CIM connection
Examples:
Remove CIM Storage Subsystem
rmdatasource –t http –i 9.3.194.11 –p 5988
CLI 定义阶段
每一条命令行都必须定义一组参数,它们被用来定义应用程序的接口。Apache Commons CLI 使用
Options 这个类
来定义和设置参数,它是所有
Option 实例的容器。在
CLI 中,目前有两种方式来创建
Options,一种是通过构
造函数,这是最普通也是最为大家所熟知的一种方式;另外一种方法是通过
Options 中定义的工厂方式来实现。
CLI 定义阶段的目标结果就是创建
Options 实例。
根据上面给出的具体命令行设计,我们可以用如下代码片段为添加数据源操作定义
Options:
清单
1. 定义
Options 代码片段
// 创建
Options 对象
Options options = new Options();
// 添加
-h 参数
options.addOption("h", false, "Lists short help");
// 添加
-t 参数
options.addOption("t", true, "Sets the HTTP communication protocol for CIM connection");
其中
addOption() 方法有三个参数,第一个参数设定这个
option 的单字符名字,第二个参数指明这个
option 是否
需要输入数值,第三个参数是对这个
option 的简要描述。在这个代码片段中,第一个参数只是列出帮助文件,不
需要用户输入任何值,而第二个参数则是需要用户输入
HTTP 的通信协议,所以这两个
option 的第二个参数分
别为
false 和
true,完整的代码及注释请参考第二章节的命令行开发部分。
CLI 解析阶段
在解析阶段中,通过命令行传入应用程序的文本来进行处理。处理过程将根据在解析器的实现过程中定义的规则
来进行。在
CommandLineParser 类中定义的
parse 方法将用
CLI 定义阶段中产生的
Options 实例和一组字符串作
为输入,并返回解析后生成的
CommandLine。
CLI 解析阶段的目标结果就是创建
CommandLine 实例。
根据上面给出的具体命令行设计,我们可以用如下代码片段为添加数据源操作解析
Options:
清单
2. 解析
Options 代码片段
CommandLineParser parser = new PosixParser();
CommandLine cmd = parser.parse(options, args);
if(cmd.hasOption("h")) {
}
// 这里显示简短的帮助信息
我们需要判断命令行中是不是有
h 参数,如果有,就需要应用程序列出简短的帮助信息,完整的代码及注释请参
考第二章节的命令行开发部分。
CLI 询问阶段
在询问阶段中,应用程序通过查询
CommandLine,并通过其中的布尔参数和提供给应用程序的参数值来决定需要
执行哪些程序分支。这个阶段在用户的代码中实现,CommandLine 中的访问方法为用户代码提供了
CLI 的询问
能力。
CLI 询问阶段的目标结果就是将所有通过命令行以及处理参数过程中得到的文本信息传递给用户的代码。
根据上面给出的具体命令行设计,我们可以用如下代码片段为添加数据源操作询问
Options:
清单
3. 询问
Options 代码片段
// 获取
-t 参数值
String protocol = cmd.getOptionValue("t");
if(protocol == null) {
// 设置默认的
HTTP 传输协议
} else {
}
// 设置用户自定义的
HTTP 传输协议
如果用户设置了
t 参数,getOptionValue() 方法将获取用户设定的数值,如果没有指定该参数,getOptionValue()
方法将返回
null,应用程序会根据返回的数值来决定代码的运行,完整的代码及注释请参考第二章节的命令行开
发部分。
基于
Apache Commons CLI 的命令行开发
Apache Commons CLI 简介
Apache Commons CLI 是
Apache 下面的一个解析命令行输入的工具包,该工具包还提供了自动生成输出帮助文档
的功能。
Apache Commons CLI 支持多种输入参数格式,主要支持的格式有以下几种:
1. POSIX(Portable Operating System Interface of Unix)中的参数形式,例如
tar -zxvf foo.tar.gz
2. GNU 中的长参数形式,例如
du --human-readable --max-depth=1
3. Java 命令中的参数形式,例如
java -Djava.net.useSystemProxies=true Foo
4.短杠参数带参数值的参数形式,例如
gcc -O2 foo.c
5.长杠参数不带参数值的形式,例如
ant –
projecthelp
CLI 命令代码实现
命令行程序处理流程相对比较简单,主要流程为设定命令行参数
-> 解析输入参数
-> 使用输入的数据进行逻辑处
理。下图是以
rmdatasource 为例的运行流程图,图中加入了实际实现过程中的部分逻辑。
图
1. 命令行运行流程图
清单
5 是
rmdatasource 的实现代码片段,主要逻辑在
simpleTest 函数里面。在里面我们首先载入了
ResourceBundle 用于程序的多语言支持,将运行中的输出信息预先定义在配置文件中(如
xml 或
property 文
件),然后用
ResourceBundle 读取,这样在运行时可以根据运行环境的
locale 来决定输出信息语言,也可以让用
户指定输出信息的语言。
然后程序使用
Options 定义命令行的参数,由于参数形式比较简单,所以使用了
Options 的
addOption 来创建一
个参数设定(即
option),如果有复杂参数形式,可以使用
OptionBuilder 来生成
Option,示例如下:
清单
4. 使用
OptionBuilder 生成
Options 代码片段
Option help = new Option("h", "the command help");
Option user = OptionBuilder.withArgName("type").hasArg().withDescription(
"target the search type").create("t");
// 此处定义参数类似于
java 命令中的
-D<name>=<value>
Option property = OptionBuilder.withArgName("property=value")
.hasArgs(2).withValueSeparator().withDescription(
"search the objects which have the target property and value").create("D");
Options opts = new Options();
opts.addOption(help);
opts.addOption(user);
opts.addOption(property);
在参数设定好后,程序使用
BasicParser 类来解析用户输入的参数,当参数中包含
–h 时程序打印命令行的帮助
信息(利用
Apache Commons CLI 的
HelpFormatter 自动生成),如果不包含
–h 时,程序将读取需要的
ip、
port 等参数并进行校验,校验通过后则调用内部接口进行
rmdatasource 的操作。
清单
5. rmdatasource 代码片段
public class RMDataSource {
/**
* @param args 输入参数
*/
public static void main(String[] args) {
simpleTest(args);
}
public static void simpleTest(String[] args) {
ResourceBundle resourceBundle = ResourceBundle.getBundle("message",
Locale.getDefault());
Options opts = new Options();
opts.addOption("h", false, resourceBundle.getString("HELP_DESCRIPTION"));
opts.addOption("i", true, resourceBundle.getString("HELP_IPADDRESS"));
opts.addOption("p", true, resourceBundle.getString("HELP_PORT"));
opts.addOption("t", true, resourceBundle.getString("HELP_PROTOCOL"));
BasicParser parser = new BasicParser();
CommandLine cl;
try {
cl = parser.parse(opts, args);
if (cl.getOptions().length > 0) {
if (cl.hasOption('h')) {
HelpFormatter hf = new HelpFormatter();
hf.printHelp("Options", opts);
} else {
String ip = cl.getOptionValue("i");
String port = cl.getOptionValue("p");
String protocol = cl.getOptionValue("t");
if(!CIMServiceFactory.getinstance().isIPValid(ip))
{
System.err.println(resourceBundle.getString("INVALID_IP"));
System.exit(1);
}
try {
int rc = CIMServiceFactory.getinstance().rmdatasource(
ip, port, protocol);
if (rc == 0) {
System.out.println(resourceBundle
.getString("RMDATASOURCE_SUCCEEDED"));
} else {
System.err.println(resourceBundle
.getString("RMDATASOURCE_FAILED"));
}
} catch (Exception e) {
System.err.println(resourceBundle
.getString("RMDATASOURCE_FAILED"));
e.printStackTrace();
}
}
} else {
System.err.println(resourceBundle.getString("ERROR_NOARGS"));
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
基于
Apache Commons CLI 的命令行测试
CLI 的测试可以分为两种情况,内部逻辑的测试可以用
JUnit 来实现,方便、简洁、快速;CLI 的运行可以用脚
本(在
Windows 里用
bat 脚本,Linux 上用
shell 脚本)来验证
CLI 的运行结果。
JUnit 的运行与测试
在代码清单
5 中,我们可以看到
CLI 接收的参数来源于它的一个
String 输入数组,因此我们可以在
JUnit 的
TestCase 中创建一个
String 数组来模拟输入,以下清单
6 是对
rmdatsource 的
help 有无参数情况的单元测试的代
码,仅测试了方法的返回值。
清单
6. JUnit 测试代码片段
// 测试带有
–h 参数的代码功能
public void testHelp() {
String args[]={"-h"};
assertEquals(0, RMDataSource.simpleTest(args));
}
// 测试没有带
–h 参数的代码功能
public void testNoArgs() {
String args[] = new String[0];
assertEquals(1, RMDataSource.simpleTest(args));
}
// 测试输入所有正确参数的代码功能
public void testRMDataSource() {
/**
* 此字符串参数等同于在命令行窗口输入命令
java rmdatasource -i 192.168.0.2 -p 5988 -t http
*/
String args[] = new String[]{"-i","192.168.0.2","-p","5988","-t","http"};
assertEquals(0, RMDataSource.simpleTest(args));
}
CLI 的运行与测试
开发完成后,将项目编译成
jar 包即可运行
CLI 了,假定我们的
jar 包名字是
rmdatasource.jar,则在
jar 包所在
目录运行
java –jar rmdatasource.jar –h 即可得到该
CLI 的帮助信息。同样,也可以用脚本来运行所开发的命令行
工具,对命令的返回值和输出进行校验,如下图清单
7 即为一段
shell 脚本获取命令的返回值和输出信息的代
码。
清单
7. CLI 测试代码片段
/opt/ibm/java-i386-60/bin/java -jar /tmp/test/rmdatasource.jar -h > /tmp/test/result
echo "cli return code is $?"
if [ $? -eq 0 ]
then
while read line
do
echo $line
done < /tmp/test/result
fi
总结
随着科学计算可视化及多媒体技术的飞速发展,人机交互技术不断更新,但是最传统的命令行模式依然被广泛的
应用于多个领域,因为命令行界面要较图形用户界面节约更多的计算机系统资源。在熟记命令的前提下,使用命
令行界面往往要较使用图形用户界面的操作速度要快。同时,命令行模式也更加有利于客户进行二次开发,方便
应用程序的整合。Apache Commons CLI 提供了很多实用的工具和类实现,进一步方便了我们对命令行工具的开
发,本文介绍了一个完整的实例,希望能对相关读者在以后的工作有所帮助。
参考资料
学习
.
Apache Commons CLI 官方网站:详细介绍了
Apache Commons CLI 的概念、各阶段的定义与实现以及各个
实用类的
JavaDoc。
.
Apache Commons CLI 用法简介:本技术文档列举了一些
Apache Commons CLI 中常用的
API,并给出了一
些
API 的用例。
.
JUnit Cookbook:本文档简略描述了如何使用
JUnit 来编写测试实例。
.
Java Internationalization: Localization with ResourceBundles:本技术文档描述了如何使用
ResourceBundle 来实
现程序的本土化支持。
.
developerWorks Java 技术专区:这里有数百篇关于
Java 编程各个方面的文章。
讨论
.
加入
developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他
developerWorks 用
户交流。
- 大小: 110.7 KB
- 大小: 48.7 KB
分享到:
相关推荐
Apache Commons CLI 是一个广泛使用的库,它提供了处理命令行参数的工具。这个库支持短选项(如 `-h`)、长选项(如 `--help`)、带有或不带有值的选项,以及对选项的组合和互斥处理。通过定义Option对象,你可以...
2. Apache Commons CLI: 命令行接口(CLI)工具包简化了命令行参数解析。它可以自动处理短选项、长选项、选项组合以及帮助信息的生成,让编写命令行程序变得更加简单。 3. Apache Commons Codec: 这个库提供了各种...
7. **CLI**: Commons CLI 提供了命令行接口解析的工具,帮助开发者处理命令行参数。 8. **Configurations**: 这个模块允许从不同的配置源(如XML、Properties文件)读取配置信息,方便程序配置的管理。 9. **Email...
5. **其他 Commons 组件**:除了上述组件,Apache Commons 还包括许多其他实用库,如 Commons Codec(编码解码工具)、Commons CLI(命令行接口解析)、Commons Configurations(配置文件处理)等,涵盖了网络、XML ...
7. **Apache Commons CLI**: 为命令行接口解析提供了支持,使得创建带选项和参数的命令行工具变得更加简单。 8. **Apache Commons Configuration**: 提供了灵活的配置文件处理,可以读取 XML、INI、系统属性等多种...
Java提供了丰富的类库,如`java.util.Scanner`用于用户输入处理,`java.io`包下的类用于文件操作,`java.lang.ProcessBuilder`可以调用系统命令,以及`java.nio`非阻塞I/O流等,这些都使得Java成为开发命令行工具的...
Apache Commons CLI库是Java开发中的一个实用工具,用于处理命令行接口(CLI)的解析和管理。这个库在处理命令行参数和选项时提供了一种简单而强大的方式,使得开发者可以更加灵活地构建命令行驱动的程序。"commons-...
10. **Apache Commons CLI**: 用于解析命令行参数,使得创建具有复杂选项和参数的命令行接口变得更加简单。 以上只是部分Apache Commons项目,每个jar包都有详细的API文档和示例代码,开发者可以根据具体需求选择...
7. **CLI**: Apache Commons CLI 提供了命令行接口(CLI)解析工具,帮助处理命令行参数和选项。 8. **Configurations**: Apache Commons Configurations 提供了配置文件处理工具,支持 XML、INI、Java 属性等多种...
5. **Apache Commons CLI**: 用于处理命令行接口的工具,简化了命令行参数的解析和验证。开发者可以通过CLI轻松地定义命令行选项,提高命令行程序的用户体验。 6. **Apache Commons Codec**: 提供了各种编码和解码...
Apache Commons是一套为Java开发者提供的开源工具库,它由一系列经过验证的、可重用的Java组件构成,旨在解决日常开发中的常见问题,并提高开发效率。这些工具集覆盖了广泛的领域,包括但不限于集合操作、配置管理、...
在实际应用中,使用Apache Commons CLI可以极大地提高命令行工具的易用性和健壮性。例如,通过以下步骤,开发者可以快速实现命令行参数的解析: 1. **创建Option对象**:为每个命令行选项创建一个Option对象,指定...
Apache Commons是一个非常有用的工具包,解决各种实际的通用问题。(附件中提供了该工具包的jar包,及源文件以供研究) BeanUtils Commons-BeanUtils 提供对 Java 反射和自省API的包装 Betwixt Betwixt提供将 ...
Commons CLI 是 Apache Software Foundation 的一个开源项目,全称为“Command Line Interface”,中文可译为“命令行接口”。这个工具包的主要目标是简化Java程序中处理命令行参数的过程,为开发者提供了一个灵活且...
Apache Commons CLI库是Java开发中的一个实用工具,用于处理命令行接口(CLI)参数和选项。这个库在标题中提到的"commons-cli-1.1.zip"是一个压缩包,包含了Apache Commons CLI项目的1.1版本。这个库是Apache软件...
Java Easy CLI 是一个基于 Apache Commons CLI 的轻量级命令行接口工具,它的设计目标是简化命令行参数的解析和管理。Apache Commons CLI 是一个广泛使用的 Java 库,它提供了处理命令行选项、参数和帮助信息的功能...
Apache Commons CLI库是Java开发人员用来处理命令行接口(CLI)的一个强大工具。它提供了方便的方式来定义、解析和处理命令行参数,使开发者能够构建更易于使用的命令行应用程序。本项目名为“commons-cli命令模式...
- 开发者工具:用于调试、测试和其他开发任务的命令行工具。 7. **最佳实践**: - 明确定义选项和参数,确保用户能理解其用途。 - 使用`HelpFormatter`生成清晰的帮助信息,方便用户查阅。 - 检查并处理解析...
10. **Commons CLI**:简化了命令行接口的解析,帮助开发者处理命令行参数。 每个Apache Commons子项目都有详细的文档和示例代码,方便开发者理解和使用。在"使用说明.txt"文件中,通常会包含如何导入、配置以及...
Apache Commons CLI 是一个Java库,专门用于处理命令行接口(CLI)选项和参数。这个库为Java应用程序提供了灵活且易于使用的API,使得开发者能够轻松地创建具有命令行参数的程序。在Apache Commons CLI 1.4版本的...