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

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

例如,这有效:

$ 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]

但触摸会:

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

创建三个文件。

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

答案1

首先要理解的是,有些命令允许多个参数,有些则不允许。虽然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}

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

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

$ echo {a,b,c}
a b c

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

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

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

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

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

 http://site.{one,two,three}.com

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

相关内容