Apache Commons CLI 1.3.1:具有多个参数的另一个选项之后的选项将作为ARGUMENT使用

时间:2022-05-09 17:07:23

I'm using Apache Commons CLI 1.3.1 to process some options and some of the options can take one to unlimited number arguments. A trivia example with two options would be like this

我正在使用Apache Commons CLI 1.3.1处理一些选项,一些选项可以使用一个到无限数量的参数。有两个选项的琐事示例就是这样的

usage: myProgram -optionX <arg1> <arg2> <arg3> < ... > [-optionY]
-optionX <arg1> <arg2> <arg3> < ... >   optionX takes one to unlimited
                                        number of arguments.
-optionY                                optionY is optional

What I found is that the second option optionY is always recognized as an ARGUMENT of the optionX instead of being recognized as an OPTION by itself. That means if you type myProgram -optionX arg1 arg2 -optionY in the command line, you will get three arguments (arg1, arg2, and -optionY) associated with optionX.

我发现第二个选项选项Y始终被识别为optionX的ARGUMENT,而不是单独被识别为OPTION。这意味着如果在命令行中键入myProgram -optionX arg1 arg2 -optionY,您将获得与optionX关联的三个参数(arg1,arg2和-optionY)。

Here is the code that anyone can use to reproduce the problem.

以下是任何人都可以用来重现问题的代码。

import org.apache.commons.cli.*;

public class TestCli {

public static void main(String[] args) {

    Option optObj1 = Option.builder("optionX")
                            .argName("arg1> <arg2> <arg3> < ... ")
                            .desc("optionX takes one to unlimited number of arguments.")
                            .required()
                            .hasArgs()
                            .build();

    Option optObj2 = new Option("optionY", "optionY is optional");

    Options optsList = new Options();
    optsList.addOption(optObj1);
    optsList.addOption(optObj2);

    CommandLineParser commandLineParser = new DefaultParser();

    try {

        CommandLine cmd = commandLineParser.parse(optsList, new String[]{"-optionX", "arg1", "arg2", "-optionY"});

        System.out.println("--------------------------");
        System.out.println("argument list of optionX: ");
        for (String argName : cmd.getOptionValues(optObj1.getOpt())) {
            System.out.println("arg: " + argName);
        }

        System.out.println("--------------------------");
        System.out.println("value of optionY: " + cmd.hasOption(optObj2.getOpt()));

    } catch (ParseException e) {
        System.out.println("Unexcepted option: " + e.getMessage());
    }

}
}

This is the output you'll see.

这是你会看到的输出。

--------------------------
argument list of optionX: 
arg: arg1
arg: arg2
arg: -optionY
--------------------------
value of optionY: false

Do I miss something here?

我在这里想念一下吗?

Any suggestion will be really appreciated.

任何建议都将非常感激。

1 个解决方案

#1


3  

The problem is that you are putting the long name in the short name of the option.

问题是您将长名称放在选项的短名称中。

When you use Option optObj1 = Option.builder("optionX").... or new Option("optionY", "optionY is optional"), you're setting the short name of the option, which is supposed to be only 1 character long.

当您使用Option optObj1 = Option.builder(“optionX”)....或新选项(“optionY”,“optionY是可选的”)时,您正在设置选项的短名称,该名称应该只是1个字符长。

That work well until you have a multi arguments option. In this case, the parser cannot find "o" (the first letter of your option) in his short option list and you don't have a long name set, so the parser determines that -optionY is just another argument for -optionX.

这有效,直到你有一个多参数选项。在这种情况下,解析器在其短选项列表中找不到“o”(选项的第一个字母),并且您没有设置长名称,因此解析器确定-optionY只是-optionX的另一个参数。

To solve your problem, just set the long option name of your option and it should work alright.

要解决您的问题,只需设置选项的长选项名称,它应该可以正常工作。

Example

Option.builder("x").longOpt("optionX")....

Option optObj2 = new Option("y", "optionY", hasArgs, "optionY is optional");

#1


3  

The problem is that you are putting the long name in the short name of the option.

问题是您将长名称放在选项的短名称中。

When you use Option optObj1 = Option.builder("optionX").... or new Option("optionY", "optionY is optional"), you're setting the short name of the option, which is supposed to be only 1 character long.

当您使用Option optObj1 = Option.builder(“optionX”)....或新选项(“optionY”,“optionY是可选的”)时,您正在设置选项的短名称,该名称应该只是1个字符长。

That work well until you have a multi arguments option. In this case, the parser cannot find "o" (the first letter of your option) in his short option list and you don't have a long name set, so the parser determines that -optionY is just another argument for -optionX.

这有效,直到你有一个多参数选项。在这种情况下,解析器在其短选项列表中找不到“o”(选项的第一个字母),并且您没有设置长名称,因此解析器确定-optionY只是-optionX的另一个参数。

To solve your problem, just set the long option name of your option and it should work alright.

要解决您的问题,只需设置选项的长选项名称,它应该可以正常工作。

Example

Option.builder("x").longOpt("optionX")....

Option optObj2 = new Option("y", "optionY", hasArgs, "optionY is optional");