java Apache Commons CLI 选项解析器可以忽略未知的命令行选项吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6049470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:08:01  来源:igfitidea点击:

Can Apache Commons CLI options parser ignore unknown command-line options?

javaapache-commonsapache-commons-cli

提问by Michael Ridley

I am writing a Java application that takes command line arguments which are processed using Apache Commons CLI with the GnuParser. For reasons that are not interesting to get into, I would like it to silently ignore unknown command line options instead of throwing a ParseException but I don't see a way to do that. I see that there is a stopAtNonOption boolean option on GnuParser.parse() but what I want is more like ignoreAtNonOption where it will keep processing options after encountering an unknown token.

我正在编写一个 Java 应用程序,它采用带有 GnuParser 的 Apache Commons CLI 处理的命令行参数。出于一些不感兴趣的原因,我希望它默默地忽略未知的命令行选项,而不是抛出 ParseException,但我没有看到这样做的方法。我看到 GnuParser.parse() 上有一个 stopAtNonOption 布尔选项,但我想要的更像是 ignoreAtNonOption ,它会在遇到未知标记后保留处理选项。

I could implement my own parser to accomplish this but I'm surprised there isn't this functionality built in so I thought I'd check before going down that road.

我可以实现我自己的解析器来完成这个,但我很惊讶没有内置这个功能,所以我想我会在走那条路之前检查一下。

Example code for what I'm talking about:

我正在谈论的示例代码:

try {
  CommandLine commandLine = parser.parse(options, args);
  // stopAtNonOption set to true (below) is also not what I want
  // CommandLine commandLine = parser.parse(options, args, true);
} catch (ParseException e) {
  LOG.error("error parsing arguments", e);
  throw new RuntimeException(e);
}

回答by Pascal Sch?fer

This works for me (other parsers can be derived, too):

这对我有用(也可以派生其他解析器):

public class ExtendedGnuParser extends GnuParser {

    private boolean ignoreUnrecognizedOption;

    public ExtendedGnuParser(final boolean ignoreUnrecognizedOption) {
        this.ignoreUnrecognizedOption = ignoreUnrecognizedOption;
    }

    @Override
    protected void processOption(final String arg, final ListIterator iter) throws     ParseException {
        boolean hasOption = getOptions().hasOption(arg);

        if (hasOption || !ignoreUnrecognizedOption) {
            super.processOption(arg, iter);
        }
    }

}

回答by SimoV8

As mentioned in a comment, the accepted solution is no more suitable because the processOptionmethod has been deprecated and removed.

如评论中所述,已接受的解决方案不再合适,因为该processOption方法已被弃用并已删除。

Here's my solution:

这是我的解决方案:

public class ExtendedParser extends DefaultParser {

    private final ArrayList<String> notParsedArgs = new ArrayList<>();

    public String[] getNotParsedArgs() {
        return notParsedArgs.toArray(new String[notParsedArgs.size()]);
    }

    @Override
    public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {
        if(stopAtNonOption) {
            return parse(options, arguments);
        }
        List<String> knownArguments = new ArrayList<>();
        notParsedArgs.clear();
        boolean nextArgument = false;
        for (String arg : arguments) {
            if (options.hasOption(arg) || nextArgument) {
                knownArguments.add(arg);
            } else {
                notParsedArgs.add(arg);
            }

        nextArgument = options.hasOption(arg) && options.getOption(arg).hasArg();
        }
        return super.parse(options, knownArguments.toArray(new String[knownArguments.size()]));
    }

}

Compared with the solution proposed by Pascal, it also checks for options with arguments and it keeps not parsed args in a separate list.

与 Pascal 提出的解决方案相比,它还检查带有参数的选项,并将未解析的 args 保留在单独的列表中。

回答by Emmanuel Bourg

This is not possible with Commons CLI. But there may be another way to achieve the result you expect if you give more details of your use case.

这在 Commons CLI 中是不可能的。但是,如果您提供有关用例的更多详细信息,则可能有另一种方法可以实现您期望的结果。

回答by Kung Wang

I am a very bad developer, and I do this to break the code:

我是一个非常糟糕的开发人员,我这样做是为了破坏代码:

public class EasyPosixParser extends PosixParser {
    @Override
    protected void processOption(String arg, ListIterator iter) throws ParseException
    {
        try {
            super.processOption(arg, iter);
        } catch (ParseException e) {
            // do nothing
        }
    }
}

in your main code, you do:

在您的主代码中,您执行以下操作:

    CommandLineParser commandlineParser = new EasyPosixParser();