Как мне разобрать аргументы командной строки в 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.
Я создал это. Я рад получить вопросы или пожелания.
Я пытался сохранить список парсеров Java CLI.
- авиакомпания
- Активная вилка: https://github.com/rvesse/airline
- argparse4j
- argparser
- args4j
- clajr
- кли-анализатор
- CmdLn
- Командная строка
- DocOpt.java
- дельфин гетопт
- DPML CLI (Jakarta Commons CLI2 fork)
- Доктор Матиас Ло
- Джакарта Коммонс CLI
- jargo
- jargp
- jargs
- Java-Getopt
- jbock
- JCLAP
- jcmdline
- jcommander
- jcommando
- jewelcli (написано мной)
- Просто
- jsap
- naturalcli
- Статья Object Mentor CLI (подробнее о рефакторинге и TDD)
- синтаксический-CMD
- ritopt
- Rop
- TE-Code Command
- Picocli имеет цветную справку по ANSI и автозаполнение
Купить или построить?
Многие небольшие подобные приложения, вероятно, запускают собственный синтаксический анализ командной строки, чтобы избежать дополнительной внешней зависимости.
пикокли может быть интересным. Он предназначен для включения в качестве источника в качестве более простой альтернативы теневым банкам в uberjar.
Еще одна функция, которая вам может понравиться - это цветная справка по использованию.
Особенности парсера:
- На основе аннотации: синтаксический анализ - это одна строка кода
- Все строго набрано - параметры командной строки, а также позиционные параметры
- 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));
}
}
Если вы уже используете 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