在Java中解析命令行参数的好方法是什么?
看看Commons CLI项目,那里有很多好东西 .
叶氏 .
我想你正在寻找这样的东西:http://commons.apache.org/cli
Apache Commons CLI库提供用于处理命令行界面的API .
最近的一颗冉冉升起的新星是picocli(ANSI颜色,命令行自动完成,注释和编程API等等) .
还要检查这些(较旧):
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
或滚动你自己:
For instance, 这是你使用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 .
我创造了它 . 我很高兴收到问题或功能要求 .
我一直在努力保持list of Java CLI parsers .
Airline
活动叉:https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli具有ANSI着色使用帮助和自动完成功能
我使用过JOpt,发现它非常方便:http://jopt-simple.sourceforge.net/
首页还提供了大约8个替代库的列表,检查出来并选择最适合您需求的库 .
最近有人向我指出args4j这是基于注释的 . 我很喜欢!
这是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", )
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) .
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)); } }
也许这些
picocli "a mighty tiny command line interface" . Picocli是Java的命令行参数解析器库 - 具有ANSI着色的使用帮助和命令行完成 . 嵌套的子命令,详细的用户手册以及作为源代码的能力,以避免依赖于picocli的jar也是值得注意的 .
JArgs command line option parsing suite for Java - 这个小项目提供了一个方便,紧凑,预打包和全面记录的命令行选项解析器套件,供Java程序员使用 . 最初,提供了与GNU-style 'getopt'兼容的解析 .
ritopt, The Ultimate Options Parser for Java - 虽然已经提出了几个命令行选项标准,但ritopt遵循opt包中规定的约定 .
你可能会发现这篇不幸的元文章作为一个有趣的起点:
http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html
购买还是建造?
许多类似实用程序的小应用程序可能会使用自己的命令行解析来避免额外的外部依赖 .
picocli可能很有趣 . 它被设计为作为源的一个更简单的替代方法,将阴影 jar 放入uberjar中 .
您可能喜欢的另一个功能是它的彩色使用帮助 .
解析器功能:
基于注释:解析是一行代码
强力输入所有内容 - 命令行选项以及位置参数
POSIX群集短选项( <command> -xvfInputFile 以及 <command> -x -v -f InputFile )
<command> -xvfInputFile
<command> -x -v -f InputFile
允许最小,最大和可变数量参数的arity模型,例如 "1..*" , "3..5"
"1..*"
"3..5"
子命令(可以嵌套到任意深度)
适用于Java 5及更高版本
使用帮助消息很容易使用注释进行自定义(无需编程) . 例如:
(source)
我无法抗拒添加一个屏幕截图来显示可能的用法帮助消息 . 使用帮助是您的应用程序的面貌,所以要有创意,玩得开心!
免责声明:我创建了picocli . 反馈或问题非常欢迎 .
我又写了一篇:http://argparse4j.sourceforge.net/
Argparse4j是Java的命令行参数解析器库,基于Python的argparse .
如果你熟悉gnu getopt,那里是一个Java端口:http://www.urbanophile.com/arenn/hacking/download.htm .
似乎有一些类可以做到这一点:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline @ Github看起来不错 . 它基于注释,并试图模拟Git命令行结构 .
我不建议使用Apache Common CLI库,因为它是非线程安全的 . 它使用具有静态变量和方法的有状态类来执行内部工作(例如OptionBuilder),并且只应在单线程强控制情况下使用 .
如果你想要一些轻量级(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); }
更多例子可以找到here
我知道这里的大多数人都会找到1000万个他们不喜欢我的方式的原因,但是没关系 . 我喜欢保持简单,所以我只需使用'='将键与值分开,然后将它们存储在HashMap中,如下所示:
Map<String, String> argsMap = new HashMap<>(); for (String arg: args) { String[] parts = arg.split("="); argsMap.put(parts[0], parts[1]); }
您可以随时维护一个包含您期望的参数的列表,以帮助用户以防他忘记参数或使用错误的参数...但是,如果您想要太多功能,那么此解决方案无论如何都不适合您 .
Argparse4j是我找到的最好的 . 它模仿Python的argparse库,非常方便和强大 .
正如之前提到的评论之一(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
对于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
20 回答
看看Commons CLI项目,那里有很多好东西 .
叶氏 .
我想你正在寻找这样的东西:http://commons.apache.org/cli
最近的一颗冉冉升起的新星是picocli(ANSI颜色,命令行自动完成,注释和编程API等等) .
还要检查这些(较旧):
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
或滚动你自己:
For instance, 这是你使用commons-cli解析2个字符串参数的方法:
从命令行使用:
看一下最近的JCommander .
我创造了它 . 我很高兴收到问题或功能要求 .
我一直在努力保持list of Java CLI parsers .
Airline
活动叉:https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli具有ANSI着色使用帮助和自动完成功能
我使用过JOpt,发现它非常方便:http://jopt-simple.sourceforge.net/
首页还提供了大约8个替代库的列表,检查出来并选择最适合您需求的库 .
最近有人向我指出args4j这是基于注释的 . 我很喜欢!
这是Google的命令行解析库,作为Bazel项目的一部分开源 . 我个人认为它是最好的,比Apache CLI容易得多 .
https://github.com/pcj/google-options
安装
Bazel
Gradle
Maven
用法
创建一个扩展
OptionsBase
的类并定义@Option
(s) .解析参数并使用它们 .
https://github.com/pcj/google-options
也许这些
picocli "a mighty tiny command line interface" . Picocli是Java的命令行参数解析器库 - 具有ANSI着色的使用帮助和命令行完成 . 嵌套的子命令,详细的用户手册以及作为源代码的能力,以避免依赖于picocli的jar也是值得注意的 .
JArgs command line option parsing suite for Java - 这个小项目提供了一个方便,紧凑,预打包和全面记录的命令行选项解析器套件,供Java程序员使用 . 最初,提供了与GNU-style 'getopt'兼容的解析 .
ritopt, The Ultimate Options Parser for Java - 虽然已经提出了几个命令行选项标准,但ritopt遵循opt包中规定的约定 .
你可能会发现这篇不幸的元文章作为一个有趣的起点:
http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html
购买还是建造?
许多类似实用程序的小应用程序可能会使用自己的命令行解析来避免额外的外部依赖 .
picocli可能很有趣 . 它被设计为作为源的一个更简单的替代方法,将阴影 jar 放入uberjar中 .
您可能喜欢的另一个功能是它的彩色使用帮助 .
解析器功能:
基于注释:解析是一行代码
强力输入所有内容 - 命令行选项以及位置参数
POSIX群集短选项(
<command> -xvfInputFile
以及<command> -x -v -f InputFile
)允许最小,最大和可变数量参数的arity模型,例如
"1..*"
,"3..5"
子命令(可以嵌套到任意深度)
适用于Java 5及更高版本
使用帮助消息很容易使用注释进行自定义(无需编程) . 例如:
(source)
我无法抗拒添加一个屏幕截图来显示可能的用法帮助消息 . 使用帮助是您的应用程序的面貌,所以要有创意,玩得开心!
免责声明:我创建了picocli . 反馈或问题非常欢迎 .
我又写了一篇:http://argparse4j.sourceforge.net/
Argparse4j是Java的命令行参数解析器库,基于Python的argparse .
如果你熟悉gnu getopt,那里是一个Java端口:http://www.urbanophile.com/arenn/hacking/download.htm .
似乎有一些类可以做到这一点:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline @ Github看起来不错 . 它基于注释,并试图模拟Git命令行结构 .
我不建议使用Apache Common CLI库,因为它是非线程安全的 . 它使用具有静态变量和方法的有状态类来执行内部工作(例如OptionBuilder),并且只应在单线程强控制情况下使用 .
如果你想要一些轻量级(jar大小~20 kb)并且使用简单,你可以试试argument-parser . 它可以在大多数用例中使用,支持在参数中指定数组,并且不依赖于任何其他库 . 它适用于Java 1.5或更高版本 . 下面的摘录显示了如何使用它的示例:
更多例子可以找到here
我知道这里的大多数人都会找到1000万个他们不喜欢我的方式的原因,但是没关系 . 我喜欢保持简单,所以我只需使用'='将键与值分开,然后将它们存储在HashMap中,如下所示:
您可以随时维护一个包含您期望的参数的列表,以帮助用户以防他忘记参数或使用错误的参数...但是,如果您想要太多功能,那么此解决方案无论如何都不适合您 .
Argparse4j是我找到的最好的 . 它模仿Python的argparse库,非常方便和强大 .
正如之前提到的评论之一(https://github.com/pcj/google-options)将是一个很好的选择 .
我想要添加的一件事是:
1)如果遇到一些解析器反射错误,请尝试使用较新版本的 Guava . 在我的情况下:
2)运行命令行时:
3)当您需要使用帮助时,只需输入:
对于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