bash - ディスクに書き込むことなく複数のバックグラウンドコマンドの出力をキャプチャできますか?

bash - ディスクに書き込むことなく複数のバックグラウンドコマンドの出力をキャプチャできますか?

並列化する複数のパイプラインを含むスクリプトがあります。現在は次のとおりです。

result1=$(pipeline | number | one)
result2=$(pipeline | number | two)
result3=$(pipeline | number | three)

printf 'Result 1: %s\n' "$result1"
printf 'Result 2: %s\n' "$result2"
printf 'Result 3: %s\n' "$result3"

私はこれをしたい:

result1=$(pipeline | number | one) &
result2=$(pipeline | number | two) &
result3=$(pipeline | number | three) &

printf 'Result 1: %s\n' "$result1"
printf 'Result 2: %s\n' "$result2"
printf 'Result 3: %s\n' "$result3"

ただし、割り当てはサブシェルで行われるため、これは機能しません。

ディスクの出力ファイルをリダイレクトできます。

pipeline | number | one > result1 &
pipeline | number | two > result2 &
pipeline | number | three > result3 &

wait

printf 'Result 1: %s\n' "$(<result1)"
printf 'Result 2: %s\n' "$(<result2)"
printf 'Result 3: %s\n' "$(<result3)"

しかし、一時ファイルを作成することも避けたいと思います。

readまた、さまざまなタスクにおよびを使用してみましたが、coproc問題は常に彼readまたはvar=$()ブロックのようです。

一時ファイルを生成せずにbashに複数のコマンドの出力を非同期的にキャプチャさせる方法はありますか?

ベストアンサー1

parsetあなたは(GNU Parallelの一部)を探しています。

parset result1,result2,result3 'pipeline | number | {}' ::: one two three

parset長年にわたって現場でテストされたGNU Parallelに基づいて構築されました。その結果、出力に\ n、空白、TAB、*などが含まれていると(時々発生する)不快な予期しない競合状態に直面する可能性が低くなり、問題が発生する可能性も減ります。

例1:

. env_parallel.bash
env_parallel --session
pipeline() { seq 100; }
number() { perl -pe 's/^/Foo: /'; }
one() { grep 1; }
two() { grep 2; }
three() { grep 3; }
env_parset result1,result2,result3 'pipeline | number | {}' ::: one two three
env_parallel --end-session
echo "$result3"

例2:

. env_parallel.bash
pipeline() { seq 100; }
number() { perl -pe 's/^/Foo: /'; }
one() { grep 1; }
two() { grep 2; }
three() { grep 3; }
export -f pipeline number one two three
parset result1,result2,result3 'pipeline | number | {}' ::: one two three
echo "$result3"

(GNUパラレルする一時ファイルを作成しても予期しない競合が発生しても、ファイルをクリーンアップするために最善を尽くします。

おすすめ記事