Bash

如何判斷哪些命令將使用大括號擴展,哪些不會?

  • March 14, 2017

例如,這有效:

$ 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

創建三個文件。

我如何從這些命令的手冊頁中知道哪些可以使用大括號擴展?

首先要了解的是,有些命令允許多個參數,有些則不允許。雖然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實際上有自己的解析器並且還處理大括號擴展。這是獨立於外殼完成的,並在以下內容中進行了解釋man curl

您可以通過在大括號內編寫部分集來指定多個 URL 或部分 URL,如下所示:

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

因此,任何命令都可以使用大括號擴展,因為它實際上不是使用它的命令,而是在呼叫命令之前擴展大括號中的表達式的 shell。Curl 令人困惑,因為它有自己的類似功能。

引用自:https://unix.stackexchange.com/questions/351162