当前位置: 首页 > 工具软件 > Commons CLI > 使用案例 >

commons-cli使用介绍

景国兴
2023-12-01

1.Commons CLI

Apache Commons CLI提供了解析命令行参数的API,命令行的处理共分为三个阶段:定义阶段解析阶段审讯阶段。它也可以在命令行打印详细的参数信息。
官网教程:http://commons.apache.org/proper/commons-cli/usage.html
Commons CLI的Javadoc:http://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html

Commons CLI提供了一下不同类型的参数形式

POSIX(Portable Operating System Interface of Unix)形式,如:tar -zxvf foo.tar.gz
GNU中长参数形式,如:du --human-readable --max-depth=1
Java命令中的参数形式,如:java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo
短杠带参数值的形式,如:gcc -O2 foo.c
长杠不带参数值的形式,如:ant – projecthelp

2.CLI定义阶段

Apache Commons CLI使用Options这个类来定义和设置参数,它是所有参数的容器。它提供了下面几种方法添加参数:

addOption(Option opt)

addOption(String opt, boolean hasArg, String description)

addOption(String opt, String description)

addOption(String opt, String longOpt, boolean hasArg, String description)

第二和第三个方法用于添加短名称(或名称缩写)参数,第四个方法还提供了长名称参数。而其中的boolean参数为true时,当调用getOptionValue()方法时,可以返回对应的参数只;反之,为false时,返回null。

其中,第一个方法要更复杂些。需要先创建一个Option对象,Option对象是由OptionBuilder创建的。如:

Option filesOption = OptionBuilder.withArgName("args")
            .withLongOpt("files")
            .hasArgs(2)
            .withValueSeparator(',')
            .withDescription("file names")
            .create("f");

hasArgs()方法指定参数后有几个值,withValueSeparator(char seq)指定参数值之间的分隔符。

在定义阶段,我们需要使用Options类来定义我们需要使用的命令。

方法摘要:

返回值方法名说明
OptionsaddOption(Option opt)添加一个选项实例
OptionsaddOption(String opt, boolean hasArg, String description)添加一个只包含短名称的选项
OptionsaddOption(String opt, String description)添加一个只包含短名称的选项
OptionsaddOption(String opt, String longOpt, boolean hasArg, String description)添加一个包含短名称和长名称的选项
OptionsaddOptionGroup(OptionGroup group)添加一个选项组
List<String>getMatchingOptions(String opt)获得匹配选项的长名称集合
OptiongetOption(String opt)通过长名称或短名称获得选项
OptionGroupgetOptionGroup(Option opt)获得选项所在的选项组
CollectiongetOptions()获得一个只读的选项集合
ListgetRequiredOptions()获得必须的选项集合
booleanhasLongOption(String opt)判断是否存在选项
booleanhasOption(String opt)判断是否存在选项
booleanhasShortOption(String opt)判断是否存在选项

3.CLI解析阶段

在解析阶段中,通过命令行传入应用程序的文本来进行处理。处理过程将根据在解析器的实现过程中定义的规则来进行。Commons CLI提供了一个接口CommandLineParser,而且分别实现了下面几种解析器,用于不同的场景:

DefaultParser:提供了很基础的解析功能,只能解析基础的命令行参数。
BasicParser:提供了基础的解析功能,能解析简单的命令行参数。
PosixParser:提供了解析POSIX形式参数的功能。
GnuParser:提供了解析长参数及Java命令中参数的功能。
CommandLineParser parser = new PosixParser();
CommandLine cli = parser.parse(options, args);

在解析阶段,我们需要使用DefaultParser来解析命令行参数。DefaultParser实现了CommandLineParser接口,解析命令行参数完成后会返回CommandLine对象,在审讯阶段,我们就需要CommandLine对象来完成我们实际的工作。

部分方法摘要:

返回值方法名说明
ListgetArgList()获得参数集合
String[]getArgs()获得参数数组
Option[]getOptions()获得选项数组
StringgetOptionValue(char opt)获得选项值
StringgetOptionValue(char opt, String defaultValue)获得选项值
StringgetOptionValue(String opt)获得选项值
StringgetOptionValue(String opt, String defaultValue)获得选项值
booleanhasOption(char opt)判断是否含有选项
booleanhasOption(String opt)判断是否含有选项

4.CLI询问阶段

在询问阶段中,应用程序通过查询 CommandLine,并通过其中的布尔参数和提供给应用程序的参数值来决定需要执行哪些程序分支。这个阶段在用户的代码中实现,CommandLine 中的访问方法为用户代码提供了 CLI 的询问能力。
CLI 询问阶段的目标结果就是将所有通过命令行以及处理参数过程中得到的文本信息传递给用户的代码。

if(cli.hasOption("h")) {
    HelpFormatter hf = new HelpFormatter();
    hf.printHelp("Options", options);
}

5.CLI使用

5.1CLI配置

要使用Commons CLI需要将其JAR加入到CLASSPATH,或者如下添加Maven依赖:

<dependency>
    <groupId>commons-cli</groupId>
    <artifactId>commons-cli</artifactId>
    <version>${cli-version}</version>
</dependency>

5.2Basic Parser

BasicParser和DefaultParser只能解析基础的命令行参数,如:

public static void basicParseCLI(String[] args){
    Options options = new Options();
 
    options.addOption("h", "help", false, "print options' information");
    options.addOption("d", "database", true, "name of a database");
    options.addOption("t", true, "name of a table");
 
    Option filesOption = OptionBuilder.withArgName("args")
            .withLongOpt("files")
            .hasArgs()
            .withDescription("file names")
            .create("f");
    options.addOption(filesOption);
 
//  CommandLineParser parser = new DefaultParser();
    CommandLineParser parser = new BasicParser();
    try {
        CommandLine cli = parser.parse(options, args);
        if(cli.hasOption("h")){
            HelpFormatter hf = new HelpFormatter();
            hf.printHelp("Options", options);
        }
        else {
            String database = cli.getOptionValue("d");
            System.out.println("database: " + database);
            String table = cli.getOptionValue("t");
            System.out.println("table: " + table);
            String[] files = cli.getOptionValues("f");
            System.out.println("files: " + Arrays.asList(files));
 
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

命令行参数:

-d database -t table -files file1 file2
-database database -t table -files file1 file2

输出:

database: database
table: table
files: [file1, file2]

5.3POSIX Parser

PosixParser可以解析POSIX形式的命令行参数和Java命令中参数形式,如:

public static void posixParseCLI(String[] args){
 
    Options options = new Options();
    options.addOption("h", "help", false, "print options' information");
    options.addOption("d", "database", true, "name of a database");
    options.addOption("t", true, "name of a table");
 
    Option filesOption = OptionBuilder.withArgName("args")
            .withLongOpt("files")
            .hasArgs()
            .withDescription("file names")
            .create("f");
    options.addOption(filesOption);
 
    // hasArgs()指定后跟参数值得个数
    Option property = OptionBuilder.withArgName("property=name")
            .hasArgs()
            .withValueSeparator()
            .withDescription("use value for a property")
            .create("D");
    options.addOption(property);
 
    CommandLineParser parser = new PosixParser();
    try {
        CommandLine cli = parser.parse(options, args);
        if(cli.hasOption("h")){
            HelpFormatter hf = new HelpFormatter();
            hf.printHelp("Options", options);
        }
        else {
            String database = cli.getOptionValue("d");
            System.out.println("database: " + database);
            String table = cli.getOptionValue("t");
            System.out.println("table: " + table);
            String[] files = cli.getOptionValues("f");
            System.out.println("files: " + Arrays.asList(files));
 
            Properties properties = cli.getOptionProperties("D");
            String ext = properties.getProperty("ext");
            System.out.println("property ext = " + ext);
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

命令行参数:

-d database -ttable -files file1 file2 -Dext=java

输出:

database: database
table: table
files: [file1, file2]
property ext = java

5.4GNU Parser

GnuParser可以解析长参数及Java命令中参数,如:opt=value。

public static void gnuParseCLI(String[] args){
    Options options = new Options();
    options.addOption("h", "help", false, "print options' information");
    options.addOption("d", "database", true, "name of a database");
    options.addOption("t", true, "name of a table");
 
    // withValueSeparator(char sep)指定参数值之间的分隔符
    Option filesOption = OptionBuilder.withArgName("args")
            .withLongOpt("files")
            .hasArgs()
            .withValueSeparator(',')
            .withDescription("file names")
            .create("f");
    options.addOption(filesOption);
 
    Option property = OptionBuilder.withArgName("property=name")
            .hasArgs()
            .withValueSeparator()
            .withDescription("use value for a property")
            .create("D");
    options.addOption(property);
 
    CommandLineParser parser = new GnuParser();
    try {
        CommandLine cli = parser.parse(options, args);
        if(cli.hasOption("h")){
            HelpFormatter hf = new HelpFormatter();
            hf.printHelp("Options", options);
        }
        else {
            String database = cli.getOptionValue("database");
            System.out.println("database: " + database);
            String table = cli.getOptionValue("t");
            System.out.println("table: " + table);
            String[] files = cli.getOptionValues("f");
            System.out.println("files: " + Arrays.asList(files));
 
            Properties properties = cli.getOptionProperties("D");
            String ext = properties.getProperty("ext");
            String dir = properties.getProperty("dir");
            System.out.println("property ext: " + ext + "\tdir:" + dir);
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

命令行参数:

--database=database -t table --files=file1,file2 -Dext=java -Ddir=dir

输出:

database: database
table: table
files: [file1, file2]
property ext: java dir:dir

 

 类似资料: