GNU Parallelを使用して各入力引数に対してコマンドを実行してみました。その引数をコマンドの作業ディレクトリとして使用しました(コマンドラインに追加せず)。
基本的に私がすべきことは次のとおりです。
/foo -> "cd /foo; mycmd"
/bar -> "cd /bar; mycmd"
/baz -> "cd /baz; mycmd"
Parallelは代替文字列を--workdir
サポートして、{}
私が望むことをするようです。
--workdir mydir
--wd mydirジョブは mydir ディレクトリで実行されます。デフォルトは、ローカルコンピュータの現在のディレクトリとリモートコンピュータのログインディレクトリです。
<...>
mydir には GNU Parallel の代替文字列を含めることができます。
-n0
引数がコマンドラインに追加されるのを防ぐために、または以下を試しました-N0
。
--max-args 最大パラメータ
-n 最大パラメータコマンドラインごとに最大 max-args 個の引数を使用します。
<...>
-n 0は1つのパラメータを読み込みますが、コマンドラインに0つのパラメータを挿入することを意味します。
しかし、これはうまくいかないようです。
$ mkdir -p $HOME/{foo,bar,baz}
$ printf '%s\n' $HOME/{foo,bar,baz} | parallel --workdir '{}' -n0 'pwd'
parallel: Error: Cannot change into non-executable dir : No such file or directory
前のスペースに注意してください:
。これは、GNU並列処理のミスではなく、workdirが空の文字列として評価されることを示します。前に固定文字列を追加すると、{}
これが明らかになります。この場合、すべてのpwdは対応する固定文字列を印刷します。
$ printf '%s\n' $HOME/{foo,bar,baz} | parallel --workdir '/{}' -N0 'pwd'
/
/
/
私は何が間違っていましたか?
答え1
私は最も単純なものが次のようになると信じています:
printf '%s\n' $HOME/{foo,bar,baz} | parallel 'cd {} && myprg'
あなたできるUsed--workdir
ですが、この場合は明らかに機能しません。 GNU Parallelでは、コマンドテンプレートに代替文字列と{}
含めるパラメータが必要なことがよくあります--workdir
。
thenを使用すると、thenは空で失敗する可能性がある-n0
ため役に立ちません。使用する場所ごとに同じ文字列で評価されます。{}
--workdir
{}
したがって、解決策はを使用することですが、{}
害のない場所で使用することです。
parallel --workdir {} 'true dummy {}; myprg' ::: $HOME/{foo,bar,baz}
または、{==}
ビルドコマンドの静的部分を使用します。
parallel --workdir {} '{= $_="myprg" =}' ::: $HOME/{foo,bar,baz}
個人的に私はこのcd {}
バージョンを好みます。何をしたいのかを確認する方が簡単だと思います。
答え2
AFAICTは引数のすべてのコマンドを拡張する--workdir
ためのものではありません。{...}
それにもかかわらず、GNUはparallel
シェルを実行してユーザーが提供したコードを解釈するので、いつでも次のことができます。
... | PARALLEL_SHELL=sh parallel 'CDPATH= cd -P -- {} && mycmd'
(これは実行するシェルを決定するための経験的な方法sh
に頼るのではなく、シェルを強制し、いくつかの問題を解決します。)parallel
cd
GNU機能がまったく必要ない場合は、GNUでparallel
GNUを使用すると、GNUとシェルのオーバーヘッドと信頼できないシェル組み込み機能を回避できます。xargs
env
parallel
cd
... | xargs -rd '\n' -P8 -I{} env -C {} mycmd