
我有一個四行文字文件,每行有 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
/ -0
still 會阻塞引號和反斜杠,並刪除前導空格。對於 GNU xargs
(您必須使用它,因為您已經在使用-P
GNU 擴充功能),最好是將-d '\n'
每一行輸入作為單獨的參數傳遞
xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"
(bash
對1
輸入的每一行調用一次調用,其中 和 當前行的內容作為單獨的參數,在內聯 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