在 Groovy 中解析命令行选项

学习如何向您的 Groovy 应用程序添加选项。
45 位读者喜欢这篇文章。
Woman sitting in front of her computer

Ray Smith

最近一篇文章 介绍了在 Java 中解析命令行选项。因为我非常喜欢 Groovy,并且 Groovy 非常适合编写脚本,而且比较 Java 和 Groovy 解决方案也很有趣,所以我决定改写 Seth 的文章,但使用 Groovy。

安装 Groovy

Groovy 基于 Java,因此需要安装 Java。您的 Linux 发行版的存储库中可能包含最新且不错的 Java 和 Groovy 版本。或者,您可以按照 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 属性。这是一个字符串,如果调用 usage() 方法,它将被打印出来。

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

在第 3 行,我们定义了选项 'a',将其 longOpt 字段设置为 'alpha',并将其描述设置为 '激活 alpha 功能'。

类似地,在第 4 行,我们定义了选项 'c',将其 longOpt 字段设置为 'config',并指定此选项接受一个名为 'config' 的参数。此外,这是一个 required 选项(听起来很有趣,我知道),其描述是 '设置配置文件'。

在这里稍微停顿一下,介绍一些背景知识,您可以在上面的 CliBuilder 链接中阅读所有关于这些各种选项的信息。更一般地说,以 longOpt: 'alpha' 形式编写的内容是 Groovy 表示法,用于将键值对条目放入 Map 实例中,您可以在 此处 阅读相关内容。在这种情况下,每个键都对应于 CliBuilder 提供的同名方法。如果您想知道像下面这样的行发生了什么

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

那么,值得一提的是,Groovy 允许我们在某些情况下省略括号;所以上面等同于

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

即,这是一个方法调用。此外,Groovy 允许位置参数和命名参数,后者使用键:值语法。

继续!在第 6-9 行,我们调用 CliBuilder 实例 cliparse() 方法,传递 args——一个由 Groovy 运行时创建的 String 值数组,其中包含来自命令行的参数。此方法返回一个选项 Map,其中键是预定义选项的短格式——在本例中为 'a' 和 'c'。如果解析失败,则 parse() 发出 usage 消息,一个合理的错误消息,并返回一个 null 值,因此我们不必使用 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 <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 <config> Set config file
$

太棒了,CliBuilder 实例方法 parse() 注意到没有为 'c' 提供参数。

最后,让我们尝试同时使用这两个选项,并为 'c' 提供一个参数,以长格式

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

看起来不错!

由于 'c' 选项的想法是提供一个配置文件,我们也可以告诉 CliBuilder 实例此参数的类型是 File,它将返回 File 而不是 String。但我们将其留到以后再说。

所以,这就是在 Groovy 中解析命令行选项的方法。

Groovy 资源

Groovy 网站有很多很棒的文档。另一个很棒的 Groovy 资源是 Mr. Haki,特别是 这篇关于 CliBuilder 的精彩文章

学习 Groovy 的另一个重要原因是 Grails,这是一个非常高效的全栈 Web 框架,构建在 Hibernate、Spring Boot 和 Micronaut 等优秀组件之上。

接下来阅读什么
标签
Chris Hermansen portrait Temuco Chile
自从 1978 年毕业于不列颠哥伦比亚大学以来,我一直离不开各种计算机,自 2005 年以来一直是全职 Linux 用户,1986 年至 2005 年一直是全职 Solaris 和 SunOS 用户,在此之前是 UNIX System V 用户。

评论已关闭。

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.