Bash

為什麼 GNU 不能與“bash -c”並行工作?

  • March 6, 2017
% 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

它不是你傳遞給parallelorenv命令的xargs命令,而是一個 shell 命令行(就像你傳遞命令一樣eval)。

就像 for eval, in parallel 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 -cwith echo 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,則在您的系統上執行它)執行它。

在這裡,您可以使用 GNUxargs而不是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不能用於任意數據。

引用自:https://unix.stackexchange.com/questions/349483