プロセスが完了したときのみ出力全体を表示

プロセスが完了したときのみ出力全体を表示

これは私のスクリプトです。

#! /bin/bash

ret=0
file_out1=$(mktemp)
file_out2=$(mktemp)

(echo first start; sleep 2s; echo first finish;) &> $file_out1 &
ret=$?
P1=$!
(echo second start; sleep 1s; echo second finish;) &> $file_out2 &
ret=$?
P2=$!

wait $P1 $P2 || ret=$?

cat $file_out1
cat $file_out2

exit $ret

ここで出力は次のようになります。

first start
first finish
second start
second finish

ただし、出力は次のようになります。

second start
second finish
first start
first finish

私の言葉は、完了するcat $file_out1とすぐに実行しなければならず、完了するとすぐに実行しなければならないという意味です。P1cat $file_out2P2

また、P1が正常に終了し、P2も正常に終了することを確認したいと思います。最後に、どちらか一方P1にエラーがあるかどうかをどうやって知ることができますかP2

このスクリプトでは$ret機能しません(常にexit 0)。実行したら、から来たか$retどうP1かを知っておくとよいでしょうP2。たとえば、戻りコードx1と戻りコードx2P1があります。P2ゼロ以外の終了コードがある場合、プログラムはゼロ以外の戻りコードで終了します。

アップデート1:

一つaskubuntuで返信--group各コマンドの出力がコマンドが完了するのを待つ(混合出力を防ぐ)、パラレルコマンドのパラメータを使用することをお勧めします。

表示されるコマンドはですparallel --group 'echo -n {};sleep {};echo {}' ::: 1 3 2 4

このコマンドはマイコンピュータで動作します。しかし、私の状況でこのコマンドを使用する方法は理解できません。

私の言葉は、私がどのように得ることができるのですか?

second start
second finish
first start
first finish

echo first start; sleep 2s; echo first finish;gnuを使用しながら同時にコマンドを入力する場合echo second start; sleep 1s; echo second finish;

アップデート2:

現在私が使用しているコードは次のとおりです。

#! /bin/bash

function first {
    echo first start
    sleep 2s
    echo first finish
}
function second {
    echo second start
    sleep 1s
    echo second finish
}

export -f first && export -f second

parallel -j2 ::: first second

これは実際に私の問題を解決しました。

ベストアンサー1

各ジョブが終了したらすぐに出力を表示したいと思いますが、出力を縮小しないようにしてください。だからファイルにバッファリングすることです。大丈夫です。出力の前に sed を貼り付けて、表示されたときに表示されるようにすることもできます。その後、必要に応じて並べ替えます。これは、予測不能なデータボリュームとストレージオーバーフローのリスクを防ぐためです。

あなたのエラー:

  • バックグラウンドプロセスを分岐すると、&最終状態にアクセスできなくなります(予想されるものとはret=$?異なります)。
  • 完了するのを待つと、どのプロセスが最初に終了するか、各プロセスの最終状態を時間内にキャプチャするかどうかを予測することはできませんwait。プロセスが終了した後は、プロセスの最終状態が次のようになっても遅すぎます。 、wait得る。予測できません。1270

あなたの風は、順番に実行するのと同じフィードバックを得ながら、並列性とソース最小化の持続時間の利点を得ることです。

独自のボックスで実行し、出力競合を管理し(flockファイル記述子がクリーン)、最終状態をどこかに記録するように強制します。繰り返しますが、ファイル記述子はきれいです。

編集する@AhmadIsmailエディタが言ったように、GNU Parallelはオールインワンソリューションです。とにかく、このままにしておいてください。

#!/bin/bash
# wrap background
mybackground(){
 tmp=$(mktemp) && trap "rm -f $tmp" RETURN
 exec {safe1}>&1 {safe2}>&2 1>$tmp 2>$tmp # swap descriptors
 (eval $@) # work
 echo $? >&$fdstatus # report status 
 exec >&$safe1 2>&$safe2 # restore descriptors
 flock 1 cat $tmp # report output
}
(
mybackground "echo first start; sleep 2s; echo first finish;exit 2" &
mybackground "echo second start; sleep 1s; echo second finish" &
) {fdstatus}> >(
  while read rc;do ((sum+=rc));done;echo sum=$sum;exit $sum ## collect & sum status
) | cat # wait {fdstatus} termination

おすすめ記事