Как мне разобрать аргументы командной строки в Java?

Что такое хороший способ анализа аргументов командной строки в Java?

15.12.2008 07:46:10
См. Args4j и подробный пример того, как его использовать: martin-thoma.com/how-to-parse-command-line-arguments-in-java
Martin Thoma 14.02.2013 12:46:56
Похоже, я довольно опоздал на эту вечеринку, но я написал обработчик аргументов командной строки для Java и поместил его в GitHub: MainArgsHandler . Что касается закрытого потока, я думаю, что это очень полезный поток, но, возможно, его следует перенести на сайт программистов Stack Exchange для общего обсуждения программирования.
Bobulous 3.08.2014 14:24:19
@RedGlyph - похоже, SO / SE нужно упростить свои правила. Этот вопрос должен быть: How to parse java command line arguments?. Но никто действительно не хочет писать код для этого, а использовать инструмент. Но поиск инструментов и подобных
AlikElzin-kilaka 5.05.2015 05:09:07
Проголосовал за открытие. @AlikElzin: Действительно, им нужно пересмотреть процесс модерирования. Я подозреваю, что есть значок для закрытия очень многих вопросов, и это заманивает желающих быть модераторами слишком усердными.
RedGlyph 5.07.2015 17:00:08
Этот вопрос является приманкой для плохих / однострочных ответов и рекомендаций по инструментам. Он должен оставаться закрытым.
JAL 6.07.2015 18:46:27
21 ОТВЕТ
РЕШЕНИЕ

Проверьте это:

Или сверните свое собственное:


Например, вот как вы используете commons-cliдля анализа 2 строковых аргументов:

import org.apache.commons.cli.*;

public class Main {


    public static void main(String[] args) throws Exception {

        Options options = new Options();

        Option input = new Option("i", "input", true, "input file path");
        input.setRequired(true);
        options.addOption(input);

        Option output = new Option("o", "output", true, "output file");
        output.setRequired(true);
        options.addOption(output);

        CommandLineParser parser = new DefaultParser();
        HelpFormatter formatter = new HelpFormatter();
        CommandLine cmd;

        try {
            cmd = parser.parse(options, args);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            formatter.printHelp("utility-name", options);

            System.exit(1);
        }

        String inputFilePath = cmd.getOptionValue("input");
        String outputFilePath = cmd.getOptionValue("output");

        System.out.println(inputFilePath);
        System.out.println(outputFilePath);

    }

}

использование из командной строки:

$> java -jar target/my-utility.jar -i asd                                                                                       
Missing required option: o

usage: utility-name
 -i,--input <arg>    input file path
 -o,--output <arg>   output file
397
7.01.2020 20:38:17
Обратите внимание, что в отличие от многих других библиотек Apache, Apache CLI не имеет зависимостей.
Vladimir Dyuzhev 9.07.2012 12:43:37
Единственным недостатком многих проектов Apache-Commons является то, что они получают все меньше и меньше коммитов и в конечном итоге оказываются устаревшими.
Brett Ryan 17.09.2012 15:55:03
Вот страница «Сценарии использования» для проекта Apache CLI, в которой подробно рассказывается, как быстро начать его использовать: commons.apache.org/cli/usage.html
Brad Parks 3.12.2012 14:48:00
Я не думаю, что есть такой же, как Args4J / JCommander, кроме случаев, когда вы определяете интерфейс и комментируете методы? Я никогда не был в состоянии полюбить классы, которые "жутко инициализируют" частные поля ...
Trejkaz 6.01.2015 04:44:46
@RemkoPopma, ваша библиотека picocli выглядит просто великолепно, и спасибо вам за это, правда. Но я считаю, что вы делаете здесь и в других постах (редактируйте принятые ответы и рекламируйте свою библиотеку в верхней части страницы, даже не раскрывая, что это редактирование не от оригинального автора поста и это ваша библиотека), ужасно ужасное злоупотребление вашими полномочиями модерирования. Отметить это для других модов.
Alexander Malakhov 8.04.2019 11:30:05

Взгляните на проект Commons CLI , там много хорошего.

8
15.12.2008 07:50:00

Может быть эти

7
11.04.2019 23:23:21

Я использовал JOpt и нашел его очень удобным: http://jopt-simple.sourceforge.net/

На главной странице также представлен список из 8 альтернативных библиотек, посмотрите их и выберите ту, которая больше всего соответствует вашим потребностям.

23
15.12.2008 07:50:56

Yeap.

Я думаю, что вы ищете что-то вроде этого: http://commons.apache.org/cli

Библиотека CLI Apache Commons предоставляет API для обработки интерфейсов командной строки.

8
15.12.2008 07:51:38

Если вы знакомы с gnu getopt, есть порт Java по адресу: http://www.urbanophile.com/arenn/hacking/download.htm .

Кажется, есть некоторые классы, которые делают это:

5
9.02.2018 00:07:39

Вы можете найти эту мета-статью о несчастье интересной в качестве отправной точки:

http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html

6
15.12.2008 18:06:04
Этот парень довольно бесполезен: «Commons CLI. По-видимому, самый старый из предложенных вариантов, и он не получает большого уважения от комментаторов, поэтому я не очень внимательно к этому отношусь…», но все равно спасибо за ссылку.
James McMahon 29.09.2009 14:34:48

Кто-то недавно указал мне на args4j, основанный на аннотациях. Мне это и вправду нравится!

21
18.04.2013 12:39:44
+1 для Args4J! Чрезвычайно дружелюбный, гибкий и понятный. Я думаю, что это должна быть стандартная библиотека для создания приложений Java CLI.
Zearin 18.07.2013 15:46:08
Замечательно, что он может обрабатывать неупорядоченные (отсортированные по полевому порядку) печатные данные, что JCommander не может, и это более гибко.
Daniel Hári 7.02.2017 21:26:21
@ DanielHári Только для информации, эта функциональность была добавлена ​​в JCommander (где-то в конце февраля 2017 года).
Nathan 30.11.2017 12:56:39

Взгляните на более свежий JCommander .

Я создал это. Я рад получить вопросы или пожелания.

311
29.09.2014 19:01:37
Рад, что вам нравится JCommander :-) Я не хотел добавлять слишком много семантики к тому, как обрабатываются флаги, поэтому вам просто нужно добавить синонимы в используемых вами аннотациях: @Parameter (names = {"-h", "- -помощь "}) Я думал, что это разумный компромисс.
Cedric Beust 26.10.2010 02:13:19
Отличный инструмент. Мощный, гибкий, и вам не нужно иметь дело с раздражающими, традиционными парсерами опций.
IanGilham 7.10.2011 16:17:58
Да, я думаю, что написал бы мой собственный анализатор аргументов командной строки точно так же, как вы написали JCommander. Отличная работа.
SRG 10.03.2012 00:01:10
@CedricBeust, это замечательная библиотека, я вам очень благодарен. Поскольку мы можем определять наши собственные классы Args, которые затем можно передавать без какой-либо зависимости от класса библиотек, это делает его чрезвычайно гибким.
Brett Ryan 17.09.2012 15:50:41
уносит конкуренцию из воды!
Marcus Junius Brutus 3.07.2013 18:05:45
@ Бен Флинн хе-хе, там есть несколько довольно удивительных и интересных колес в форме. Я думаю, это в основном безвредный способ показать, что есть гораздо больше, чем один способ сделать это!
lexicalscope 31.10.2011 18:05:43
Я отмечаю, что автор JOpt Simple поддерживает очень похожий список! Нам нужен текст, чтобы превратить эти списки в таблицу со списком функций и объектов, чтобы мы, бедные пользователи, могли сделать осознанный выбор.
Tom Anderson 24.02.2012 13:23:29
Я создал Rop - github.com/ryenus/rop , в котором реализовано решение на основе аннотаций, в котором вы объявляете команды и параметры с помощью простых классов и полей, в значительной степени декларативный способ создания анализаторов командной строки. он может создавать приложения типа Git (single-cmd) или Maven (multi-cmd).
ryenus 18.12.2013 07:24:39
Большинство перечисленных проектов по сути являются заброшенными. Пройдя по списку, я бы сказал, что крупные нападающие, которые активно поддерживаются и популярны, кажутся commons-cli, jcommander, args4j, jopt-simple и picocli. Извиняюсь перед авторами таких вещей, как argparse4j и cli-parser - мне пришлось сделать несколько произвольное ранжирование, и я выбрал пятерку лучших, очевидно, что другие проекты в списке популярны и все еще находятся в активной разработке.
George Hawkins 25.09.2017 13:07:07
Я призываю кого-то указать дату последнего стабильного выпуска каждого парсера.
Sledge 1.04.2019 02:47:01

Я бы не рекомендовал использовать библиотеку Apache Common CLI, так как она не поточна. Он использует классы с состоянием со статическими переменными и методами для внутренней работы (например, OptionBuilder) и должен использоваться только в однопоточных строго контролируемых ситуациях.

2
29.08.2012 09:56:38
Следует помнить, что библиотека CLI не является поточно-ориентированной. Однако я предполагаю, что синтаксический анализ командной строки обычно выполняется в одном потоке во время запуска приложения, а затем, в зависимости от параметров, могут запускаться другие потоки.
Alexey Ivanov 30.08.2012 06:49:37

Я написал еще один: http://argparse4j.sourceforge.net/

Argparse4j - это библиотека анализатора аргументов командной строки для Java, основанная на argparse Python.

5
4.09.2012 14:24:33
Добро пожаловать в переполнение стека! Спасибо за публикацию вашего ответа! Пожалуйста, внимательно прочитайте FAQ по саморекламе .
Andrew Barber 4.09.2012 14:27:16

авиакомпания @ Github выглядит хорошо. Он основан на аннотации и пытается эмулировать структуры командной строки Git.

4
9.02.2018 00:08:56

Это библиотека синтаксического анализа командной строки Google, открытая как часть проекта Bazel. Лично я считаю, что он лучший и намного проще, чем Apache CLI.

https://github.com/pcj/google-options

Установка

Базэл

maven_jar(
    name = "com_github_pcj_google_options",
    artifact = "com.github.pcj:google-options:jar:1.0.0",
    sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)

Gradle

dependencies {
  compile 'com.github.pcj:google-options:1.0.0'
}

специалист

<dependency>
  <groupId>com.github.pcj</groupId>
  <artifactId>google-options</artifactId>
  <version>1.0.0</version>
</dependency>

Применение

Создайте класс, который расширяет OptionsBaseи определяет ваши @Option(и).

package example;

import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;

import java.util.List;

/**
 * Command-line options definition for example server.
 */
public class ServerOptions extends OptionsBase {

  @Option(
      name = "help",
      abbrev = 'h',
      help = "Prints usage info.",
      defaultValue = "true"
    )
  public boolean help;

  @Option(
      name = "host",
      abbrev = 'o',
      help = "The server host.",
      category = "startup",
      defaultValue = ""
  )
  public String host;

  @Option(
    name = "port",
    abbrev = 'p',
    help = "The server port.",
    category = "startup",
    defaultValue = "8080"
    )
    public int port;

  @Option(
    name = "dir",
    abbrev = 'd',
    help = "Name of directory to serve static files.",
    category = "startup",
    allowMultiple = true,
    defaultValue = ""
    )
    public List<String> dirs;

}

Разбери аргументы и используй их.

package example;

import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;

public class Server {

  public static void main(String[] args) {
    OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
    parser.parseAndExitUponError(args);
    ServerOptions options = parser.getOptions(ServerOptions.class);
    if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
      printUsage(parser);
      return;
    }

    System.out.format("Starting server at %s:%d...\n", options.host, options.port);
    for (String dirname : options.dirs) {
      System.out.format("\\--> Serving static files at <%s>\n", dirname);
    }
  }

  private static void printUsage(OptionsParser parser) {
    System.out.println("Usage: java -jar server.jar OPTIONS");
    System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
                                              OptionsParser.HelpVerbosity.LONG));
  }

}

https://github.com/pcj/google-options

9
9.02.2018 00:09:58
Привет, Пол. Когда я читаю ваш ответ или документацию к вашему проекту, я не имею ни малейшего представления, с какой командной строкой он может работать. Например, вы можете предоставить что-то вроде myexecutable -c file.json -d 42 --outdir ./out. И я не вижу, как вы определяете короткие / длинные / описания параметров ... Ура
olibre 13.09.2017 16:25:31

Настало время преуспеть в этом, чем CLI Commons ... :-)

Должны ли вы создать свой собственный анализатор командной строки Java или использовать библиотеку?

Многие небольшие подобные приложения, вероятно, запускают собственный синтаксический анализ командной строки, чтобы избежать дополнительной внешней зависимости. Picocli может быть интересной альтернативой.

Picocli - это современная библиотека и инфраструктура для удобного создания мощных, удобных для пользователя приложений с поддержкой GraalVM. Он находится в 1 исходном файле, поэтому приложения могут включать его в качестве источника, чтобы избежать добавления зависимости.

Он поддерживает цвета, автозаполнение, подкоманды и многое другое. Написано на Java, доступно из Groovy, Kotlin, Scala и т. Д.

Справка по минимальному использованию цветов ANSI

Особенности:

  • Основанный на аннотации: декларативный , избегает дублирования и выражает намерение программиста
  • Удобно: анализировать пользовательский ввод и запускать бизнес-логику с помощью одной строки кода
  • Все строго набрано - параметры командной строки, а также позиционные параметры
  • POSIX кластерные короткие опции ( <command> -xvfInputFileа также <command> -x -v -f InputFile)
  • Детальное управление : модель арности, которая допускает минимальное, максимальное и переменное количество параметров, например "1..*","3..5"
  • Подкоманды (могут быть вложены на произвольную глубину)
  • Многофункциональный : составные группы аргументов, разбиение аргументов в кавычках, повторяемые подкоманды и многое другое
  • Удобный для пользователя : в справочном сообщении об использовании используются цвета для контрастирования важных элементов, таких как имена опций, от остальной части использования, которые помогают снизить когнитивную нагрузку на пользователя
  • Распространите свое приложение как собственный образ GraalVM
  • Работает с Java 5 и выше
  • Обширная и дотошная документация

Справочное сообщение об использовании легко настроить с помощью аннотаций (без программирования). Например:

Расширенное справочное сообщение об использовании( источник )

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

пикокли демо

Отказ от ответственности: я создал picocli. Отзывы или вопросы очень приветствуются.

47
17.03.2020 00:51:09
Чистый гений! Обидно, этот ответ похоронен внизу. Apache Commons CLI является многословным, содержит ошибки и долгое время не обновлялся. И я не хочу использовать синтаксический анализатор CLI от Google, потому что я не хочу целевых рекламных объявлений, основанных на моей истории использования аргументов командной строки. Но все равно выглядит немного более многословно, чем пикокли.
Pete 1.09.2018 04:10:51
Я второй @ Пит здесь ... Я прошел список выше, который был пустой тратой времени с этим, похороненным внизу. Это должен быть главный ответ на милю. Отличная работа! Мои требования не могут быть покрыты Apache CLI или большинством других парсеров. Они бросали вызов даже для picocli, но он был в состоянии дать мне наиболее близкую вещь к синтаксису / поведению, которое я хотел, и был достаточно гибок, чтобы взломать то, что мне действительно нужно. В качестве бонуса это здорово смотрится благодаря материалу ANSI.
Shai Almog 1.10.2019 11:25:29
@ShaiAlmog Ответ с самым высоким рейтингом - 10 лет и он устарел. Я согласен, что рекомендация CLI Commons в 2019 году вводит в заблуждение ИМХО. Пожалуйста, подумайте над тем, чтобы переписать верхний ответ, чтобы сделать его более актуальным.
Remko Popma 2.10.2019 09:51:28
Я вижу, вы уже пробовали это, я не думаю, что это будет работать и для меня ... Если бы вы выбрали имя, такое как 1Picoli, мы могли бы отсортировать третий ответ по алфавиту ;-)
Shai Almog 3.10.2019 02:53:47
Я думаю, что причина моего изменения была в том, что я не раскрыл свою принадлежность (что я автор). У других людей не должно быть этой проблемы.
Remko Popma 3.10.2019 02:59:41

Если вы хотите что-то легкое (размер баночки ~ 20 кб) и простое в использовании, вы можете попробовать аргумент-парсер . Он может использоваться в большинстве случаев, поддерживает указание массивов в аргументе и не зависит от какой-либо другой библиотеки. Это работает для Java 1.5 или выше. Ниже приведен пример того, как его использовать:

public static void main(String[] args) {
    String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
    ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
    InputData inputData = (InputData) argParser.parse(args);
    showData(inputData);

    new StatsGenerator().generateStats(inputData);
}

Больше примеров можно найти здесь

2
15.09.2017 11:52:11
Ссылка мертва. Ты убил свой проект? :-(
beldaz 19.10.2017 19:39:29

Argparse4j - лучшее, что я нашел. Он имитирует argparse-библиотеку Python, которая очень удобна и мощна.

3
9.02.2018 00:10:52

Я знаю, что большинство людей здесь найдут 10 миллионов причин, почему им не нравится мой путь, но не берите в голову. Мне нравится делать вещи простыми, поэтому я просто отделяю ключ от значения, используя '=', и сохраняю их в HashMap следующим образом:

Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
    String[] parts = arg.split("=");
    argsMap.put(parts[0], parts[1]);
} 

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

6
19.07.2018 12:00:18

Как один из упомянутых ранее комментариев ( https://github.com/pcj/google-options ), было бы хорошим выбором для начала.

Одна вещь, которую я хочу добавить:

1) Если вы столкнулись с ошибкой отражения парсера, попробуйте использовать более новую версию гуавы. в моем случае:

maven_jar(
    name = "com_google_guava_guava",
    artifact = "com.google.guava:guava:19.0",
    server = "maven2_server",
)

maven_jar(
    name = "com_github_pcj_google_options",
    artifact = "com.github.pcj:google-options:jar:1.0.0",
    server = "maven2_server",
)

maven_server(
    name = "maven2_server",
    url = "http://central.maven.org/maven2/",
)

2) При запуске командной строки:

bazel run path/to/your:project -- --var1 something --var2 something -v something

3) Если вам нужна помощь в использовании, просто введите:

bazel run path/to/your:project -- --help
0
26.08.2018 08:29:18

Для пользователей Spring следует также упомянуть https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html и его брата-близнеца https: //docs.spring .io / spring / docs / current / javadoc-api / org / springframework / core / env / JOptCommandLinePropertySource.html (реализация JOpt с той же функциональностью). Преимущество в Spring заключается в том, что вы можете напрямую связать аргументы командной строки с атрибутами, здесь есть пример https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/ CommandLinePropertySource.html

-1
21.09.2018 00:35:08

Если вы уже используете Spring Boot, разбор аргументов происходит из коробки.

Если вы хотите запустить что-то после запуска, реализуйте ApplicationRunnerинтерфейс:

@SpringBootApplication
public class Application implements ApplicationRunner {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void run(ApplicationArguments args) {
    args.containsOption("my-flag-option"); // test if --my-flag-option was set
    args.getOptionValues("my-option");     // returns values of --my-option=value1 --my-option=value2 
    args.getOptionNames();                 // returns a list of all available options
    // do something with your args
  }
}

Ваш runметод будет вызван после успешного запуска контекста.

Если вам нужен доступ к аргументам до запуска контекста приложения, вы можете просто проанализировать аргументы приложения вручную:

@SpringBootApplication
public class Application implements ApplicationRunner {

  public static void main(String[] args) {
    ApplicationArguments arguments = new DefaultApplicationArguments(args);
    // do whatever you like with your arguments
    // see above ...
    SpringApplication.run(Application.class, args);
  }

}

И наконец, если вам нужен доступ к вашим аргументам в бине, просто введите ApplicationArguments:

@Component
public class MyBean {

   @Autowired
   private ApplicationArguments arguments;

   // ...
}
4
12.07.2019 09:45:01
Это круто :).
John Humphreys - w00te 15.04.2020 01:37:37