私が書いているbash関数では、ssh経由で複数のリモートコマンドを開始し、別々のバックグラウンドプロセスで実行させます。これらのプロセスのそれぞれは、多くの行のテキストを生成し、それらを併合してソートします。私の問題は、これらの行が混在することがあることです。つまり、1行が印刷を開始し、その行が印刷を終了する前に、別の行が同じ行に印刷を開始します。bashスクリプトで複数のバックグラウンドプロセスの行をアトミックに印刷する方法は?
私の質問は、個々の行が混ざり合わないように、このプリント出力をアトミックにする最も簡単な方法は何ですか(全行が散在していてもいいですか?私が持っていた1つのアイデアは、各並列バックグラウンドプロセスの出力を保存し、それをシリアルにマージすることでしたが、これを動作させることができませんでした(このメソッドは正しく動作する方法を知っていればうまく動作するはずです)。参考のために、ここで私が書くしようとしているスクリプトの種類の概要である:
foo() {
(
pids=()
for x in "[email protected]"
do
(
ssh $x 'some-high-latency-command-with-200-lines-of-data-output'
) &
pids+=($!)
done
for x in "${pids[@]}"
do
wait $x
done
) 2> /dev/null
}
おかげで、待機のためにその構文は、物事ビットを簡素化しますが、基本的と同じことを行いよりコンパクトな表記でループします。しかし、ファイルを作成せずにこれを行うといいですね。 – jonderry
しかし、シェルは本当にそのようなことをすることはできません。あなたはバックグラウンド 'ssh'をバックグラウンド' sshとすることができます... |一方、読書l。 do "$ l" >>ファイルをエコーします。ブロックされていない出力またはブロックバッファされた出力の代わりにラインバッファリングを実行することを唯一の目的とする無償のループのためにかなり遅くなる。後でデータを使って何をやっているかによって、後になるまでマージステップをオフにすることは、厄介な 'ssh'からシェルスクリプトへのパイプラインよりも優れており、信頼性が高くなります。 – geekosaur
私は実際に出力を 'less'にパイプし、'& 'で行のサブセットを選択して、マシン間のさまざまな統計を比較しています。私はデータを永続的に保持する必要はありません。これらは比較的短時間の実験で、8-10台までのマシンを並行して約10秒しかかかりません。しかし、私はこれらのテストを頻繁に実行しているため、個々の出力を手動で比較するのではなく、スクリプトの利点があります。 – jonderry