並列化する複数のパイプラインを含むスクリプトがあります。現在は次のとおりです。
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パラレルする一時ファイルを作成しても予期しない競合が発生しても、ファイルをクリーンアップするために最善を尽くします。