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

时光总嘲笑我的痴心妄想 提交于 2019-11-28 02:51:31

问题


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.

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);
}

回答1:


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);
        }
    }

}



回答2:


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

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.




回答3:


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.




回答4:


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();


来源:https://stackoverflow.com/questions/6049470/can-apache-commons-cli-options-parser-ignore-unknown-command-line-options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!