如何判断哪些命令会使用大括号扩展,哪些不会?

jco*_*lum 2 shell bash curl brace-expansion

例如,这有效:

$ curl -s -X GET "http://api-int.abc.com/api/{,,,}ukulele/v1/health"

这运行了 4 个 curl 命令,这正是我想要的。

同时ping不会使用大括号扩展:

$ ping {google,yahoo,microsoft}.com
usage: ping [-AaDdfnoQqRrv] [-b boundif] [-c count] [-G sweepmaxsize]
Run Code Online (Sandbox Code Playgroud)

但触摸会:

$ touch .temp/{a,b,c}.txt

创建三个文件。

我如何从这些命令的手册页中知道哪些可以使用大括号扩展?

ter*_*don 5

首先要了解的是,有些命令允许多个参数,有些则不允许。虽然touch允许多个参数,ping但不允许。在 的情况下ping,大括号扩展为多个并使用多个参数调用 ping,这是ping行不通的。在这种情况下,for 循环是更好的解决方案。此外,大括号curl是一种特殊情况(见下文)。

“哪些命令可以使用大括号扩展”的答案是全无。在将扩展输出传递给命令之前,大括号扩展由 shell 完成。换句话说,正在启动的命令是完全无关的。foo{bar,baz}to的扩展foobar foobaz由 shell 在启动命令并将扩展后的字符串作为参数传递给它之前完成。

但是,大括号扩展不会发生在引号内。换句话说,"{,,,}"和 都"{a,b,c}"保留为字符串并且不会扩展:

$ echo "{,,,}"
{,,,}
$ echo "{a,b,c}"
{a,b,c}
Run Code Online (Sandbox Code Playgroud)

要使扩展工作,您应该删除引号:

$ echo {,,,}  ## this expands to a blank string, so this is what is printed

$ echo {a,b,c}
a b c
Run Code Online (Sandbox Code Playgroud)

这记录在man bash(强调我的)的相关部分中:

大括号扩展在任何其他扩展之前执行,并且任何其他扩展的特殊字符都保留在结果中。它是严格的文本。Bash 不对扩展的上下文或大括号之间的文本应用任何句法解释。

格式正确的大括号扩展必须包含不带引号的左括号和右括号,以及至少一个不带引号的逗号或有效的序列表达式。

现在,您感到困惑的原因是它curl实际上有自己的解析器,并且还处理大括号扩展。这是独立于外壳完成的,并在man curl

您可以通过在大括号内编写部分集来指定多个 URL 或 URL 的一部分,如下所示:

 http://site.{one,two,three}.com
Run Code Online (Sandbox Code Playgroud)

因此,任何命令都可以使用大括号扩展,因为它实际上不是使用它的命令,而是在调用命令之前扩展大括号中表达式的 shell。Curl 令人困惑,因为它有自己的类似功能。