
私は、約 5 つか 6 つの異なるプログラムにデータをパイプし、最終結果をタブ区切りファイルに出力する bash シェル スクリプトを持っています。
次に、別の同様のデータセットに対して同じ操作を再度実行し、2 番目のファイルに出力します。
次に、両方のファイルを別のプログラムに入力して比較分析します。たとえば、簡素化するために
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv
私の質問は、ステップ 1 とステップ 2 を同時に実行し (例: & を使用)、両方が完了したときにのみステップ 3 (AnalysisProg) を起動するにはどうすればよいかということです。
THX
ps AnalysisProg はストリームまたは FIFO では動作しません。
答え1
を使用しますwait
。例:
Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg
意思:
- Data1 と Data2 パイプをバックグラウンドジョブとして実行する
- 二人とも終わるまで待つ
- AnalysisProgを実行します。
例えば、この質問。
答え2
ファイルが 2 つしかない場合は、cxw の回答が間違いなく最適なソリューションです。2 つのファイルが単なる例で、実際には 10000 個のファイルがある場合、サーバーに過負荷がかかるため、「&」ソリューションは機能しません。そのためには、GNU Parallel のようなツールが必要です。
ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv
GNU Parallel の詳細については、以下を参照してください。
- 簡単な紹介については、紹介ビデオをご覧ください。 https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- チュートリアル (man parallel_tutorial) を実行してください。コマンド ラインが役に立つはずです。
答え3
これを行う 1 つの方法は次のようになります。
AnalysisProg <<PREPROCESS /dev/stdin
$(
{ process1=$( pipe | line | 1 >&2 & echo $! )
process2=$( pipe | line | 2 >&2 & echo $! )
while ps -p $process1 $process2 >/dev/null; do
sleep 1
done
} 2>&1
)
#END
PREPROCESS
この方法では、両方のパイプラインをバックグラウンドで実行しますが、出力をstdinに結合する前に実行が完了するのを待ってから、ヒアドキュメントで評価され、AnalysisProgに渡されます。wait
これはwhile ps
ループしますが、シェルによっては、wait
プロセスを待つように指示すると、反対するかもしれません現在のシェルの子ではありません。
また、上記の方法では出力が照合されるため、両方のプロセスが同時に書き出すことに注意してください。代わりに、それらを別々にしたい場合、または一方を他方に追加したい場合は、次のようにすることができます。
AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)
答え4
これを使ってみてください。
rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
if [ $? -ne 0 ]
then
AnalysisProg -i Data1res.csv Data2res.csv
exit 0
fi
done