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

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

Ответ 1

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

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


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

Ответ 2

Взгляните на более поздний JCommander.

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

Ответ 3

Я пытался поддерживать список парсеров Java CLI.

Ответ 4

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

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

Ответ 5

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

Ответ 6

  Это 2019 год, время, чтобы сделать лучше, чем CLI Commons... :-)

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

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

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

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

Minimal usage help with ANSI colors

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

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

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

Extended usage help message (источник)

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

picocli demo

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

Ответ 7

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

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 (s).

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

Ответ 8

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

Ответ 9

Yeap.

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

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

Ответ 10

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

Ответ 13

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

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

Ответ 14

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

Ответ 15

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

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

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

Ответ 16

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

Ответ 17

Если вы хотите что-то легкое (размер jar ~ 20 kb) и прост в использовании, вы можете попробовать argument-parser. Он может использоваться в большинстве случаев использования, поддерживает указание массивов в аргументе и не имеет никакой зависимости от какой-либо другой библиотеки. Он работает для 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);
}

Дополнительные примеры можно найти здесь

Ответ 18

Argparse4j лучше всего я нашел. Он подражает Python argparse libary, который очень удобен и эффективен.

Ответ 19

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

}

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

@Component
public class MyBean {

   @Autowired
   private ApplicationArguments arguments;

   // ...
}

Ответ 20

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

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

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

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

Ответ 21

Это 2017. Использование JavaFX должно быть в порядке. Вызовите getParameters, чтобы получить Application.Parameters.

Ответ 22

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