使用 xargs 和單獨的變數並行化函數

使用 xargs 和單獨的變數並行化函數

我有一個四行文字文件,每行有 1、2、3 和 4。另外,我有一個想要並行化的函數:foo() { echo "$1 is not $2"; }

我導出函數:export -f foo

現在我想使用文字檔案中的參數來呼叫該函數xargs以進行並行化。我還想a=0在函數中使用變數 ( ) 作為參數。所以,我將該函數稱為:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} $a'

這會忽略變數 ( a=0)。並輸出:

“1 不是”...“4 不是”等等

如果我調用:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} 0'它有效並且我得到正確的輸出

「1 不是0「……」4不是0“ ETC

但我需要使用變數 ( a=0) 來呼叫它,而不是使用零。我該怎麼做?

答案1

在 shell 程式碼中嵌入{}始終是一個壞主意,因為它會引入命令注入漏洞。將資料作為單獨的(非代碼)參數傳遞總是更好。

另外-I, without -d/ -0still 會阻塞引號和反斜杠,並刪除前導空格。對於 GNU xargs(您必須使用它,因為您已經在使用-PGNU 擴充功能),最好是將-d '\n'每一行輸入作為單獨的參數傳遞

xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"

bash1輸入的每一行調用一次調用,其中 和 當前行的內容作為單獨的參數,在內聯 shell 腳本中$a稱為$1和)。$2

或與-I

xargs -a txt -rd'\n' -P2 -I'{}' bash -c 'foo "$1" "$2"' bash {} "$a"

在這裡,您可以切換到zsh具有zargs可自動載入函數的函數,該函數可以像 GNUxargs一樣進行並行處理,包括無需執行單獨的 shell 呼叫或匯出函數的函數xargs

$ autoload zargs
$ foo() print -r - $1 is not $2
$ zargs -P2 -I {} {1..4} -- foo {} $a
1 is not foo
2 is not foo
3 is not foo
4 is not foo

答案2

使用 GNU Parallel 時,它看起來像這樣:

foo() { echo "$1 is not $2"; }
export -f foo
seq 4 > txt
a=0
cat txt | parallel foo {} $a

相關內容