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

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

23 ответа

Решение

Недавняя восходящая звезда - это picocli (цвета ANSI, автозаполнение командной строки, аннотации и программный API и многое другое).

Также проверьте это (старше):

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


Например, вот как вы используете 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

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

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

Купить или построить?

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

пикокли может быть интересным. Он предназначен для включения в качестве источника в качестве более простой альтернативы теневым банкам в uberjar.

Еще одна функция, которая вам может понравиться - это цветная справка по использованию.

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

Особенности парсера:

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

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

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

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

пикокли демо

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

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

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

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

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

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

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

Это библиотека синтаксического анализа командной строки 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

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

Если вы уже используете 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;

   // ...
}

Yeap.

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

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

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

  • picocli "могущественный крошечный интерфейс командной строки". Picocli - это библиотека синтаксического анализа аргументов командной строки для Java - с цветной справкой по использованию ANSI и завершением командной строки. Также заслуживают внимания вложенные подкоманды, подробное руководство пользователя и возможность включения в качестве источника, чтобы избежать зависимости от банки с пикокли.
  • Набор синтаксического анализа параметров командной строки JArgs для Java - этот крошечный проект предоставляет удобный, компактный, предварительно упакованный и полностью документированный набор анализаторов параметров командной строки для использования программистами Java. Первоначально синтаксический анализ совместим с GNU-стилем 'getopt'.

  • ritopt, анализатор окончательных параметров для Java - хотя было предложено несколько стандартов параметров командной строки, ritopt следует соглашениям, предписанным в пакете opt.

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

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

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

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

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

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

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

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

Я хочу показать вам свою реализацию: ReadyCLI

Преимущества:

  • для ленивых программистов: очень небольшое количество классов для изучения, просто посмотрите два небольших примера в README в репозитории, и вы уже на 90% усвоили; просто начните кодировать свой CLI / Parser без каких-либо других знаний;ReadyCLI позволяет кодировать CLI наиболее естественным образом;
  • он разработан с учетом опыта разработчиков ; он в основном использует шаблон проектирования Builder и функциональные интерфейсы для лямбда-выражений, что позволяет очень быстро кодировать;
  • он поддерживает параметры , флаги и подкоманды;
  • он позволяет анализировать аргументы из командной строки и создавать более сложные и интерактивные интерфейсы командной строки;
  • CLI может быть запущен на стандартном вводе-выводе так же легко, как и на любом другом интерфейсе ввода-вывода, таком как сокеты;
  • он дает отличную поддержку для документации команд.

Я разработал этот проект, так как мне были нужны новые функции (параметры, флаг, подкоманды), которые можно было бы использовать в моих проектах самым простым способом.

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

Если вы хотите что-то легкое (размер баночки ~ 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);
}

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

Как один из упомянутых ранее комментариев ( 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

Взгляните на Spring Shell

Возможности Spring Shell включают

  • Простая модель программирования на основе аннотаций для добавления пользовательских команд.
  • Использование функции автоматической настройки Spring Boot в качестве основы для стратегии плагина команд
  • Завершение табуляции, раскрашивание и выполнение скрипта
  • Настройка командной строки, имени файла истории оболочки, обработки результатов и ошибок
  • Динамическое включение команд на основе конкретных критериев домена
  • Интеграция с API проверки компонентов
  • Уже встроенные команды, такие как очистить экран, великолепная помощь, выход
  • Художественные таблицы ASCII с форматированием, выравниванием, причудливыми рамками и т. д.

Для пользователей 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

Другие вопросы по тегам