私は、入力をさまざまな方法で並行して処理し、入力された結果の行を書き出そうとしています。現在のアプローチは次のとおりです。
# process_parallel.sh
read input
parallel --colsep ' ' --linebuffer 'echo $input | {}' \
::: 'python process1.py' ./process2.sh ./process3
文脈は要約すると次のようになります。
(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh
上記は機能しますが、重要な欠点が 1 つあります。入力が読み込まれるまでプロセスは開始されません。これにはしばらく時間がかかる可能性があるため、すぐにプロセスを開始し、各プロセスに完全な標準入力を並列パイプで渡します。
どうすればそれを達成できるでしょうか?
答え1
GNU Parallel では、実行するためのデータがなければ新しいジョブを開始しないようにするために、かなりの作業が行われました。これは、入力がない場合に一部のプログラムが重大な失敗を起こすためです。したがって、GNU Parallel の設計に反する作業を行うことになります。
入力を複製するにはtee
、置換を使用して処理します。
cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null
process1
、、process2
が直ちに開始されますprocess3
。ただし、出力は混在する可能性があるため、出力を使用する必要がある場合は、別のファイルにリダイレクトする必要があります。
cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null
答え2
2 つのラッパー スクリプトを用意します。まず、process_parallel.sh を変更して、各プロセスが 3 つのファイル (file1、file2、file3 など) から入力を読み取るように指示します。
次に、標準入力を 3 つのファイルに並列に送信する 2 番目のラッパー スクリプトを作成します。
#!/bins/bash
#parallelise input
# let's call this file parallelise
parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3"
さて、あなたは次のように始めます:
./process_parallel_sh; cat InputFile | parallelise;
答え3
Parallel には--tee
、次のように使用できるオプションがあります。
(sleep 1; echo "short input arriving late") |\
parallel --colsep ' ' --linebuffer --pipe --tee ::: 'python process1.py' ./process2.sh ./process3 |\
./collate_results.sh