在Groovy中解析命令行选项的方法

314 阅读4分钟

安装Groovy

Groovy是基于Java的,所以它需要安装Java。最近的、合适的Java和Groovy版本可能都在你的Linux发行版的软件库中。另外,你也可以按照groovy-lang.org上的说明来安装Groovy。

对于Linux用户来说,一个不错的选择是SDKMan,它可以用来获取多个版本的Java、Groovy和许多其他相关工具。在本文中,我使用了我的发行版OpenJDK11和SDKMan的最新Groovy版本。

在Groovy中解析命令行选项

当我们创建一个脚本时--一种简短的、通常是非正式的程序,可以从命令行中运行,我们通常会遵循在命令行中向脚本传递参数的做法。这方面的一个很好的例子是ls ,用来列出某个文件夹中的所有文件和子文件夹,也许会显示属性,并按最后修改日期的倒序排序,如:。

$ ls -lt /home/me

像这样显示我的主文件夹的内容。

total 252
drwxr-xr-x 5 me me 4096 Aug 10 12:23 Downloads
drwx------ 11 me me 4096 Aug 10 08:59 Dropbox
drwxr-xr-x 27 me me 12288 Aug 9 11:58 Pictures
-rw-rw-r-- 1 me me 235 Jul 28 16:22 wb.groovy
drwxr-xr-x 2 me me 4096 Jul 20 22:04 Desktop
drwxrwxr-x 2 me me 4096 Jul 20 15:16 Fixed
drwxr-xr-x 2 me me 16384 Jul 19 08:49 Music
-rw-rw-r-- 1 me me 433 Jul 7 13:24 foo
drwxr-xr-x 6 me me 4096 Jun 29 10:25 Documents
drwxr-xr-x 2 me me 4096 Jun 14 22:15 Templates
-rw-rw-r-- 1 me me 803 Jun 14 11:33 bar

当然,命令的参数可以通过检查它们并决定在每种情况下做什么来处理;但这最终是一种重复的工作,可以通过使用为此目的设计的库来避免。

Seth的Java文章介绍了Apache Commons CLI库,这是一个处理命令行选项的伟大API。事实上,这个库非常棒,以至于开发Groovy的好心人在Groovy的安装中默认提供了它。因此,一旦你安装了Groovy,你就可以通过以下方式访问这个库了 groovy.cli.picocli.CliBuilder来访问这个库,这个库已经默认为你导入了。

下面是一个Groovy脚本,它使用这个CLI构建器来实现与Seth的Java程序相同的结果。

1 def cli = new CliBuilder(usage: 'ho.groovy [-a] -c')
2 cli.with {
3    a longOpt: 'alpha', 'Activate feature alpha'
4    c longOpt: 'config', args:1, argName: 'config', required: true, 'Set config file'
5 }
6 def options = cli.parse(args)
7 if (!options) {
8    return
9 }
10 if (options.a) {
11    println' Alpha activated'
12 }
13 if (options.c) {
14    println "Config set to ${options.c}"
15 }

为了便于讨论,我在这里加入了行号。把这个脚本保存在一个叫做ho.groovy的文件中,不要加上行号。

在第1行,我们定义了变量cli并将其设置为一个新的CliBuilder实例,并定义了使用属性。这是一个字符串,如果调用**usage()**方法,它将被打印出来。

在第2-5行,我们使用Groovy添加到对象的 with()方法,加上CliBuilder定义的DSL,来设置选项定义。

在第3行,我们定义了选项**"a**",将其longOpt字段设置为**"alpha**",将其描述为**"激活特征alpha**"。

同样,在第4行,我们定义了选项**"c**",将其longOpt字段设置为**"config**",并指定该选项需要一个参数,其名称为**"config**"。此外,这是一个必需的选项(听起来很有趣,我知道),它的描述是**"设置配置文件**"。

在此简单介绍一下背景,你可以在上面的CliBuilder链接中阅读所有关于这些不同的选项。一般来说,写成longOpt:'alpha'是Groovy的符号,用来表示要放在Map实例中的键值条目,你可以在这里阅读。在这种情况下,每个键都对应于由CliBuilder提供的同名方法。如果你想知道像这样的一行是怎么回事。

a longOpt: 'alpha', 'Activate feature alpha'

的行文是怎么回事,那么不妨提一下,Groovy允许我们在某些情况下去掉小括号;所以上面的内容相当于。

a(longOpt: 'alpha', 'Activate feature alpha')

也就是说,这是一个方法调用。此外,Groovy允许定位参数和命名参数,后者使用key: value语法。

前进!前进在第6-9行,我们调用CliBuilder实例cliparse()方法,传递args--一个由Groovy运行时创建的、包含命令行参数的String值数组。这个方法返回一个选项的Map,其中的键是预定义选项的简写形式--在这个例子中是'a'和'c'。如果解析失败,parse()会发出使用信息和合理的错误信息,并返回一个空值,所以我们不必使用try-catch块(这在Groovy中并不经常见到)。所以在这里--第8行--我们只是返回,因为我们所有的工作已经完成。

在第10-12行,我们检查是否在命令行中包含了选项'a',如果是,就打印一条消息说明。

同样,在第13-15行,我们检查命令行中是否包含了选项"c",如果是,则打印一条信息,显示提供给它的参数。

运行命令

让我们运行该脚本几次;首先是在没有参数的情况下。

$ groovy ho.groovy
error: Missing required option: c
usage: ho.groovy [-a] -c
 -a,--alpha Activate feature alpha
 -c,--config  Set config file
$

注意到关于缺少所需选项'c'的抱怨。

然后是有'c'选项但没有参数。

$ groovy ho.groovy -c
error: Missing argument for option: c
usage: ho.groovy [-a] -c
 -a,--alpha
Activate feature alpha
 -c,--config  Set config file
$

很好,CliBuilder的实例方法parse()注意到没有向'c'提供参数。

最后,让我们试试两个选项和一个参数给'c',以它们的长形式。

$ groovy ho.groovy --alpha --config bar
Alpha activated
Config set to bar
$

看起来不错

由于'c'选项的想法是提供一个配置文件,我们也可以告诉CliBuilder实例,这个参数的类型是文件,它将返回这个参数而不是一个字符串。但我们会把这个问题留到下一天。

所以,你有了它--Groovy中的命令行选项解析。

Groovy资源

Groovy网站有很多很棒的文档。另一个伟大的Groovy资源是Haki先生,特别是这篇关于CliBuilder的可爱文章

学习Groovy的另一个很好的理由是Grails,它是建立在Hibernate、Spring Boot和Micronaut等优秀组件之上的一个非常有成效的全栈网络框架。