所以我有一个Options
个实例,其中包含其他选项(注意isRequired()
):
options.addOption(OptionBuilder
.withLongOpt("seq1")
.withDescription("REQUIRED : blah blah")
.hasArg().isRequired().create());
options.addOption(OptionBuilder
.withLongOpt("seq2")
.withDescription("REQUIRED : blih blih")
.hasArg().isRequired().create());
options.addOption(new Option("?", "help", false,
"print this message and exit"));
如果parser.parse(args)
和seq1
不存在,我打电话给seq2
会引发异常 - 但是我希望打印我的消息并且不会抛出任何异常 - 如何解决这个问题?这会在line.hasOption("help")
中引发NPE,当然:
CommandLine line = null;
try {
CommandLineParser parser = new GnuParser();
// parse the command line arguments
line = parser.parse(options, args);
} catch (ParseException e) {
if (line.hasOption("help")) { //NPE
usage(0);
}
System.err.println("Parsing failed. Reason: " + e.getMessage());
usage(1);
}
private static void usage(int exitCode) {
// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("Smith Waterman", OPTIONS, true);
System.exit(exitCode);
}
答案 0 :(得分:7)
改编自here
的解决方案private static final Options OPTIONS = new Options();
private static final Options HELP_OPTIONS = new Options();
OPTIONS.addOption(OptionBuilder
.withLongOpt("seq1")
.withArgName("file1")
.withDescription(
"REQUIRED : the file containing sequence 1")
.hasArg().isRequired().create());
// etc
final Option help = new Option("?", "help", false,
"print this message and exit");
HELP_OPTIONS.addOption(help);
OPTIONS.addOption(help);
// later
CommandLineParser parser = new GnuParser();
CommandLine line = parser.parse(HELP_OPTIONS, args, true); // true so it
// does not throw on unrecognized options
if (line.hasOption("help")) {
usage(0); // calls exit
}
line = parser.parse(OPTIONS, args);
如果有更优雅的话,我很乐意接受它
答案 1 :(得分:1)
根据您的使用情况,这可能有用也可能没用。我的如下:
例如:
$ controller startall -rsrc foo -dir bar -where baz
使用参数完成的第一件事是确定命令是什么。为此我设置了一个TaskFactory,它查看第一个参数,剥离任何前导连字符,然后查找它是否是已知任务。我有一个'帮助'任务,让我的用户可以这样做:
$ controller -help
和
$ controller help
每个任务还有一个帮助选项,因此用户可以执行以下操作:
$ controller startall -help
但是,这可能对你没有帮助。我会发布一个替代方案。
答案 2 :(得分:1)
我在解析之前使用了以下检查,以确保-h
或--help
否决了其他所有内容。
// check if help is requested
if (Arrays.asList(args).contains("-h")
|| Arrays.asList(args).contains("--help")) {
usage(0); // print usage with exit 0
}
// parse options
不是最好的解决方案,但它符合我的需求。
答案 3 :(得分:0)
Commons CLI没有处理选项间依赖关系,正如您所发现的那样。在您的情况下,--help
选项会修改seq1
和seq2
的要求。
唯一真正的解决方案是使所有选项不是必需的,并在命令行解析完成后自行进行依赖性验证。
答案 4 :(得分:0)
扩展您选择的解析器以忽略未知选项:
Can Apache Commons CLI options parser ignore unknown command-line options?
然后解析参数两次,一次用于-help
参数,一次用于正常参数。第一次通过你应该传递“忽略”标志,第二次你不应该。
或者,解析选项两次,一次查找-help
并捕获(并忽略)MissingOptionException
,然后再次使用常规参数。