Может ли анализатор параметров командной строки Apache Commons игнорировать неизвестные параметры командной строки? - PullRequest
20 голосов
/ 18 мая 2011

Я пишу Java-приложение, которое принимает аргументы командной строки, которые обрабатываются с помощью Apache Commons CLI с GnuParser. По причинам, которые неинтересны, я хотел бы, чтобы он игнорировал неизвестные параметры командной строки, а не создавал исключение ParseException, но я не вижу способа сделать это. Я вижу, что в GnuParser.parse () есть логическая опция stopAtNonOption, но я хочу больше походить на ignoreAtNonOption, где он продолжит обработку параметров после обнаружения неизвестного токена.

Я мог бы реализовать свой собственный синтаксический анализатор, чтобы выполнить это, но я удивлен, что эта функциональность не встроена, поэтому я решил проверить, прежде чем идти по этому пути.

Пример кода того, о чем я говорю:

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

Ответы [ 4 ]

28 голосов
/ 23 декабря 2011

Это работает для меня (другие парсеры тоже могут быть получены):

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 голосов
/ 14 ноября 2018

Как уже упоминалось в комментарии, принятое решение больше не подходит, поскольку метод processOption устарел и удален.

Вот мое решение:

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

}

По сравнению с решением, предложенным Паскалем, он также проверяет параметры с аргументами и сохраняет непарсированные аргументы в отдельном списке.

1 голос
/ 18 июля 2011

Это невозможно с Commons CLI.Но может быть и другой способ достичь ожидаемого результата, если вы дадите более подробную информацию о вашем сценарии использования.

0 голосов
/ 11 ноября 2011

Я очень плохой разработчик, и я делаю это, чтобы взломать код:

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

в вашем основном коде вы делаете:

    CommandLineParser commandlineParser = new EasyPosixParser();
...