2009-07-29 4 views
138

Я пишу небольшое приложение командной строки на Java. Это приложение должно работать с набором параметров и команд, аналогично svn.Библиотека Java для анализа параметров командной строки?


Примеры

app url command1 
app url command2 --parameter2 -x 
app url command1 --param-with-argument argument 
app --parameter url command1 
app --no-url command2 
app --help 


Требуются

  • Exists библиотеку простой в использовании для Ja ва
  • Поддерживает разбор таких командных строк
  • (Bonus) Автоматически создает соответствующую помощь
+1

Близко связанный старый вопрос: http://stackoverflow.com/questions/435740/are-there-good-java-libraries-that-facilitate-building-command-line-applications – Jonik

+1

Возможный дубликат [Есть ли хорошие синтаксический анализатор командной строки для Java?] (http://stackoverflow.com/questions/367706/is-there-a-good-command-line-argument-parser-for-java) –

+1

Это хороший вопрос, который заслуживает быть на http://softwarerecs.stackexchange.com/. –

ответ

82

Я фанат Commons CLI.

Вы можете настроить его для понимания команд, флагов (с короткими и длинными именами), независимо от того, нужны или нет определенные команды/переключатели или имеют значения по умолчанию. Он даже имеет функциональность для печати полезного сообщения типа --help.

На странице Usage Scenarios есть несколько хороших примеров того, как ее можно использовать.

+0

Hy. Это было давно, но я не могу заставить apache cli поймать мои команды, только флаги. И я не мог найти пример. =/ –

54

Попробуйте args4j:http://args4j.kohsuke.org

Я предпочитаю args4j с Commons CLI. (И я использовал оба варианта.)

С args4j вам не нужно вызывать никаких функций. Все сделано для вас! (Параметры устанавливаются в поле объекта через отражение.)

+10

Мы также используем args4j. Один из недостатков заключается в том, что вы не можете указать многозначные параметры в стиле '-file input1.txt input2.txt'. Вам нужно дополнительно указать опцию перед каждым значением ('-file input1.txt -file input2.txt'), что может быть недостатком, если вы хотите использовать расширение bash (так что' -file input * .txt' является ** не ** возможно) – MRalwasser

+2

Проект перенесен на http://args4j.kohsuke.org/ –

+0

Многозначные опции больше не поддерживаются по состоянию на args4j 2.0.23 ... – ochedru

28

JewelCLI - Java library for command-line parsing that yields clean code. Он использует Проксированные интерфейсы, сконфигурированные с помощью аннотаций, для динамического создания API-интерфейса с поддержкой типа для параметров командной строки.

Интерфейс Пример параметра Person.java:

import uk.co.flamingpenguin.jewel.cli.Option; 

public interface Person { 
    @Option String getName(); 
    @Option int getTimes(); 
} 

Пример использования интерфейса параметра Hello.java:

import static uk.co.flamingpenguin.jewel.cli.CliFactory.parseArguments; 
import uk.co.flamingpenguin.jewel.cli.ArgumentValidationException; 

public class Hello { 
    public static void main(String [] args) { 
     try { 
      Person person = parseArguments(Person.class, args); 
      for (int i = 0; i < person.getTimes(); i++) 
       System.out.println("Hello " + person.getName()); 
     } catch(ArgumentValidationException e) { 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

Сохранение копии файлов выше в один каталог и скачать JewelCLI 0.7.6 JAR в этот каталог также.

Скомпилируйте и запустите пример в Bash на Linux/Mac OS X/etc.:

javac -cp jewelcli-0.7.6.jar:. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar:. Hello --name="John Doe" --times=3 

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

javac -cp jewelcli-0.7.6.jar;. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar;. Hello --name="John Doe" --times=3 

Запуск примера должно привести следующий вывод:

Hello John Doe 
Hello John Doe 
Hello John Doe 
+0

Как вы можете видеть, JewelCLI делает синтаксический анализ командной строки простым и безопасным типом. У этого также нет никакого багажа зависимости, который тянется, что является редкостью в наши дни. –

+0

Благодарим за исправление URL @deterb :) –

+0

Благодарим за исправления ссылок @flamingpenguin :) –

3

JSAP выглядит довольно хорошо для меня.

http://sourceforge.net/projects/jsap/

+0

Информация: Последний выпущенный файл JSAP был в 2006 году – MRalwasser

+0

Возможно, он старый, но все же работает как очарование для меня. Однако сложные зависимости типа «Если параметр A задан, параметр B должен быть меньше A» не может быть выражен автоматически. – kap

15

Это также стоит смотреть на --jopt-simple.

Он пытается оценить синтаксисы опций командной строки POSIX getopt() и GNU getopt_long(). ' Кажется, что у вас есть какая-то общность в сообществе, в частности, в командной строке parsing lib выбора для OpenJDK (и Minecraft!).

19

Для полноты давайте добавим JCommander https://github.com/cbeust/jcommander

public class JCommanderTest { 
    @Parameter 
    public List<String> parameters = Lists.newArrayList(); 

    @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") 
    public Integer verbose = 1; 

    @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") 
    public String groups; 

    @Parameter(names = "-debug", description = "Debug mode") 
    public boolean debug = false; 
} 

и пример использования

CommanderTest jct = new JCommanderTest(); 
String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; 
new JCommander(jct, argv); 

Assert.assertEquals(jct.verbose.intValue(), 2); 
+1

От http://jcommander.org/: «JCommander: потому что жизнь слишком коротка, чтобы анализировать параметры командной строки». –

+0

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

3

Я использую аеролифт для проекта, я работаю, кажется, работает довольно хорошо:

https://github.com/airlift/airline

Простой Maven depen зидент, что вам нужно добавить:

<dependency> 
    <groupId>io.airlift</groupId> 
    <artifactId>airline</artifactId> 
    <version>0.6</version> 
</dependency> 

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

Можно увидеть пример здесь, если это полезно:

https://github.com/mneedham/neo4j-web-importer/blob/master/src/main/java/org/neo4j/dataimport/Neo4jImporter.java

+1

К сожалению, это затягивается в 1,8 МБ зависимости (Guava). Размер утилиты командной строки, которую я пишу, вырос только в 10 раз, просто для поддержки параметров командной строки ... – cambecc

52

Вот список относительно до настоящего времени (по состоянию на август 2017) библиотек, которые отвечают на ваш вопрос.

Если вы ищете рекомендации, я рекомендую JOpt Простой или JewelCli.

+2

JCommander является одним из самых современных в этом списке. –

+3

Как и в случае с 12 мая 2015 года, JOpt Simple по-прежнему используется в OpenJDK. Это похоже на самый полезный отзыв, о котором я могу думать. – Ivar

+2

Да, Ивар, я согласен с вами в том, что JOpt Simple не только прост в использовании, но и завершен. JCommander подойдет тем, у кого есть фетиш для привязки аннотаций. –

4

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

Чтобы использовать его, добавьте

<dependency> 
    <groupId>com.github.jankroken</groupId> 
    <artifactId>commandline</artifactId> 
    <version>1.7.0</version> 
</dependency> 

к вашему ПОМ, и объявить доступные параметры следующим образом:

public class CommandOptions { 
    private List<String> commands = null; 
    private boolean parameter = false; 
    private boolean url = true; 
    private boolean help = false; 

    @LooseArguments 
    public void setCommands(List<String> commands) { 
    this.commands = commands; 
    } 

    @LongSwitch("parameter") 
    @Toggle(true) 
    public void setParameter(boolean parameter) { 
    this.parameter=parameter; 
    } 

    @LongSwitch("noURL") 
    @Toggle(false) 
    public void setUrl(boolean url) { 
    this.url = url; 
    } 

    @longSwitch("help") 
    @Toggle(true) 
    public void setHelp(boolean help) { 
    this.help = help; 
    } 

    // getters 
} 

, а затем на самом деле разобрать командную строку, сделайте

public final static void main(String[] args) { 
    try { 
    CommandOptions options = CommandLineParser.parse(CommandOptions.class, args, OptionStyle.SIMPLE); 

    // and then you can pass options to your application logic... 

    } catch 
    ... 
    } 
} 

Обратите внимание, что он еще не содержит автоматически сгенерированный текст справки. Это было прототипировано, но прервано. Легко создать базовый текст справки для простых случаев, но для более сложных конфигураций (ae доступные параметры для приложения, такие как «find» или «gcc»), результат будет не очень приятным, и вы скорее всего захотите самостоятельно контролируйте макет.

Смежные вопросы