我正在嘗試在 Windows 下curl使用 terraform 的配置器運行命令(呼叫) 。local-exec它cmd /C根據日志運行。
粘貼在終端中的相同命令可以正常作業。
resource "null_resource" "search_indexes" {
for_each = local.indexes_set
provisioner "local-exec" {
command = <<EOT
curl https://${var.cognitive_search_name}.search.windows.net/indexes?api-version=2021-04-30-Preview --header 'Accept: application/json' --header 'api-key: ${var.key}' --data '@${each.key}'
EOT
}
}
輸出如下(摘自進度報告):
module.(...).search_indexes["test-index.json"] (local-exec): Executing: ["cmd" "/C" "curl ...
exit status 6.
curl: (6) Could not resolve host: application // actually part of first header argument
curl: (6) Could not resolve host: 1...F' // actually part of second header argument, api-key
所以我看到它與cmd /C--header 引數中空格后的單詞一起運行,并且被認為是新的 URL。
在引數周圍使用雙引號,例如--headers,一些轉義,但它仍然給出相同的錯誤。
放置在 Windows 終端中的復制粘貼命令可以正常作業。
我懷疑cmd或 terraform 做了一些事情來改變命令列,所以它看起來不正確。我怎樣才能實作正確的行為?
uj5u.com熱心網友回復:
在 Unix 和 Windows 之間,在命令列上參考和轉義的程序和約定是完全不同的。
在 Unix 上,參考和轉義是 shell 本身的一個問題,并且 Unix shell 通常將單引號的內容理解'為完全逐字的文本,而 的內容"可以包含一些插值元字符,但空格仍然是字面意思,而不是分隔符。shell 將標記化處理為一組引數,并將這些引數作為字串陣列傳遞給程式。
在 Windows 上,參考和轉義是正在運行的程式的關注點1,而不是命令解釋器的關注點cmd.exe。您鍵入的命令列將(或多或少)完全按照您撰寫的方式傳遞給您正在運行的程式 -curl在這種情況下 -完全由該程式決定哪些符號喜歡"和'可能意味著什么以及在哪里畫出不同論點之間的界限。
實際上,Windows 上的大多數現代 CLI 應用程式要么是使用 Microsoft Visual C 構建的,要么是使用其他一些模擬其命令列決議約定的軟體構建的。如果curl是這樣的程式(很可能,因為它是用 C 撰寫的),那么不幸的是相關規則非常復雜,但出于您的目的,我們可以將其簡化為幾個關鍵事實:
- 單引號字符
'按字面意思表示。與 Unix 不同,它不代表逐字文本。 - 您可以使用雙引號字符
"來表示應按字面意思使用空格而不是用作引數分隔符的序列。
因此,為了撰寫可在 Unix 和 Windows 之間移植的命令列,您將需要使用雙引號字符"并確保在引號內插入的字串不包含任何會被任何一方解釋為特殊的字符一組決議規則。
在您的情況下,我認為只要您可以確定所指的變數都不包含引號字符、$字符或任何其他 Unix shell 可能在雙引號內解釋為特殊的任何內容,則如下所示:
command = <<-EOT
curl "https://${var.cognitive_search_name}.search.windows.net/indexes?api-version=2021-04-30-Preview" --header "Accept: application/json" --header "api-key: ${var.key}" --data "@${each.key}"
EOT
由于 Unix 和 Windows 之間存在顯著的架構差異,撰寫可移植命令列非常具有挑戰性,這也是Terraform 檔案建議將配置器作為最后手段的原因之一。如果可能的話,通常最好使用專門的提供商來發出這樣的請求,但我對您在此處請求的 API 不夠熟悉,無法知道哪個提供商可能會提供它。
1從技術上講,命令解釋器自己做一些決議來處理環境變數替換%%FOO%%和 I/O 重定向序列,比如管道和>/<標記。
因此,命令解釋器有自己單獨的轉義語法,如果您的命令列最終包含任何命令解釋器的特殊字符,它可能會發揮作用。
幸運的是,命令解釋器的決議器也"對作為關閉其某些特殊處理的標記有一些基本的了解,但我們仍然需要注意%%VARIABLE%%引號內的序列,因此您需要確保要替換的變數不要'不包含類似的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/443511.html
