為什麼 GNU 不能與“bash -c”並行工作?
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}" :1 :2 % echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {} %
我希望第二行也能起到同樣的作用。
parallel
已經在 shell 中執行命令(它是哪個 shell 是通過使用啟發式方法確定的(目的是呼叫與從中parallel
呼叫的 shell 相同的 shell )。您可以設置變數來修復 shell)。parallel``$PARALLEL_SHELL
它不是你傳遞給
parallel
orenv
命令的xargs
命令,而是一個 shell 命令行(就像你傳遞命令一樣eval
)。就像 for
eval
, inparallel arg1 arg2
,parallel
將這些參數與它們之間的空格連接起來(所以它變成arg1 arg2
),並且該字元串被傳遞給<the-shell> -c
.
parallel
對於在’s 的標準輸入上傳遞的參數,parallel
以該特定 shell 所期望的格式引用它們(這是一項困難且容易出錯的任務,這就是為什麼您會發現在parallel
’s Changelog 中修復了很多錯誤的原因(截至 2017 年 3 月 6 日,有些仍未修復))並將其附加到該命令行。因此,例如,如果從內部呼叫
bash
,echo "foo'bar" | parallel echo foo
將作為命令行
bash -c
進行並行呼叫。echo foo foo\'bar
如果從內部rc
(或與PARALLEL_SHELL=rc
)呼叫rc -c
withecho foo foo''''bar
。在你的:
parallel bash -c 'echo :\$1' '' {}
parallel
連接那些給出的參數:bash -c echo :$1 {}
並以
{}
正確格式為您呼叫的 shell 進行擴展和引用,將呼叫的內容parallel
傳遞給in和目前參數 in 。<that-shell> -c``bash -c echo``:$1``$0``$1
這不是如何
parallel
工作的。在這裡,您可能想要:printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
要查看有什麼
parallel
作用,您可以在strace -fe execve
(如果不是 Linux,則在您的系統上執行它)執行它。在這裡,您可以使用 GNU
xargs
而不是parallel
獲得更接近您期望的更簡單的處理:printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
另請參閱https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html上的討論
請注意,在 中
bash -c 'echo foo' '' foo
,您正在$0
為該內聯腳本創建空字元串。我會避免這種情況,因為它$0
也用於錯誤消息中。比較:$ bash -c 'echo x > "$1"' '' / : /: Is a directory
和。
$ bash -c 'echo x > "$1"' bash / bash: /: Is a directory
另請注意,不加引號的變數具有非常特殊的含義,
bash
通常echo
不能用於任意數據。