我正在使用 GNU 並行並想了解 - 如何將單個字串傳遞給每個並行命令?
舉個例子,GNU 平行文檔顯示如何將檔案從目前目錄移至另一個目錄:
ls | parallel mv {} destdir
那麼有沒有辦法單獨取得/列印傳遞給並行的每個檔案?
平行處理案例
我需要並行處理檢查多個站點並記錄
- http 回傳碼(2xx、4xx、5xx)
- 來源網址
- 最終目標URL
- 捲曲退出程式碼
這是執行此操作的程式碼:
unset return_code_array
unset destination_url_array
unset exit_code_array
while read -r return_code_var destination_url_var exit_code_var; do
destination_url_array+=("$destination_url_var")
exit_code_array+=("$exit_code_var")
return_code_array+=("$return_code_var")
done < <(printf '%s\n' "${all_valid_URLs_array[@]}" | parallel -j 20 -k 'curl --max-time 20 -sL -o /dev/null -w "%{response_code} %{url_effective} " {}; printf "%s %s\n" "$?" ')
因此,我有三個數組,它們保存了條目的每個相應行的 HTTP 返回代碼、最終目標 URL 以及curl 退出代碼狀態all_valid_URLs_array
。我同時需要對每個進行一些處理destination_url_var
- 例如比較它是否與來源 URL 匹配,但不知道如何獲取傳遞給並行的字串。
目前,我正在上述循環之後運行第二個循環進行此類處理,但想知道我是否可以完成。
謝謝。
答案1
在您的範例中'curl … {}; printf "%s %s\n" "$?" '
(為什麼是第二個%s
?)是一段單引號的 shell 程式碼。在其中您可以{}
多次使用:
curl … {}; printf "%s %s\n" "$?" {}
或創建一個變數並根據需要多次使用它。變數的名稱可以是描述性的,這是一個優點。還有另一個優點:一般來說,替換的內容可以是很長的字串,多次替換可能會使傳遞到特定 shell 的{}
程式碼變得臃腫。 parallel
IMO 最好替換一次並讓 shell 保存字串並重複使用它:
source_URL={}; curl … "$source_URL"; printf "%s %s\n" "$?" "$source_URL"
對於 GNU,嵌入shell 程式碼parallel
是安全的。{}
這是這個答案中明確提到的例外:切勿嵌入{}
shell 程式碼!。您可能已經知道這一點,這句話是針對一般受眾的。
請注意,您需要read
在主循環中進行調整,它現在必須讀入四變數。這樣您就可以將來源 URL 從內部傳輸parallel
到主循環,您可以在其中進行比較destination_url_var
或執行任何您想要的操作。
在這種方法中,「無論你想要什麼」都不是並行的。
curl
如果您捕獲運行的 shell 程式碼內的單獨變數的輸出parallel
(而不是僅列印它以在 外部捕獲parallel
),那麼您將能夠進行比較(或任何您想要的)那裡, 在平行下。例如printf
有條件的。只要 的內部以parallel
外部期望的形式產生輸出,就由您在哪裡實現所需的邏輯read
。
傳遞給的 shell 程式碼parallel
仍然需要用單引號引起來。隨著它的增長,您可能需要在這段程式碼中使用(嵌入)單引號;那麼引用就會變得有些複雜且可讀性較差。在這種情況下,請考慮將程式碼移至單獨的腳本中,您可以在其中獨立引用。您將從主腳本中調用它,如下所示:
while read … ; done < <( … | parallel -j 20 -k 'path/to/separate_script {}' )
separate_script
在替換的字串內部{}
將可用為$1
(不要忘記雙引號它)。