GNU 並行用法 - 如何取得目前傳遞的字串到並行?

GNU 並行用法 - 如何取得目前傳遞的字串到並行?

我正在使用 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 的{}程式碼變得臃腫。 parallelIMO 最好替換一次並讓 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(不要忘記雙引號它)。

相關內容