GNU parallelが「bash -c」で機能しないのはなぜですか?


回答:


11

parallel(それはによって決定されるシェルれ、既にシェルでコマンドを実行しますparallel(意図が1が同じシェルを起動するという経験則を使用してparallel呼び出されたから)。あなたが設定できる$PARALLEL_SHELLシェルを修正するための変数)。

これparallelは、envor xargsコマンドの場合のように渡すコマンドではなく、(コマンドの場合のように)シェルコマンドラインですeval

forと同様にeval、inはparallel arg1 arg2parallelそれらの引数を間にスペースを入れて連結し(そうなるとarg1 arg2)、その文字列がに渡され<the-shell> -cます。

parallelの標準入力で渡される引数については、parallelその特定のシェルで期待される形式でそれらを引用符で囲みます(困難でエラーが発生しやすいタスクです。そのため、parallelの変更ログ(いくつかは、まだ2017年3月6日の時点で固定されていない)されている)、そのコマンドラインに追加します。

たとえば、内から呼び出された場合bash

echo "foo'bar" | parallel echo foo

コマンドラインとして並列呼び出しbash -cがありecho foo foo\'barます。そして、からrc(またはPARALLEL_SHELL=rcrc -cで呼び出された場合echo foo foo''''bar

あなたの中で:

parallel bash -c 'echo :\$1' '' {}

parallel 以下を与える引数を連結します:

bash -c echo :$1  {}

し、{}あなたが呼んでいるシェルのための適切なフォーマットに展開して引用されたparallelから、にすることを渡さ<that-shell> -cれた呼び出しますbash -c echo:$1$0とで現在の引数$1

それはどのようにparallel機能するかではありません。ここでは、おそらく次のようになります。

printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'

動作を確認するにparallelは、それを実行strace -fe execveします(Linux以外の場合は、システムで同等のもの)。

ここでは、xargs代わりにGNU を使用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通常、任意のデータには使用できません。


4
モン・デュー!これは、GNU Parallelの作者が書いたよりも良い答えです。
Ole Tange
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.