これは私のスクリプトです。
#! /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
とすぐに実行しなければならず、完了するとすぐに実行しなければならないという意味です。P1
cat $file_out2
P2
また、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
得る。予測できません。127
0
あなたの風は、順番に実行するのと同じフィードバックを得ながら、並列性とソース最小化の持続時間の利点を得ることです。
独自のボックスで実行し、出力競合を管理し(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