2016-05-28 9 views
2

を終了します。出口bashスクリプトサブプロセスの一つは、私は私のスクリプトのいくつかのバックグラウンド・プロセス</p> <pre><code>run_gui() { exec ... # the real commands here } </code></pre> <p>類似してい<code>run_ai1(), run_ai2</code>機能を実行している

は、その後、私は関数を実行し、これら3つのプロセスが終了するのいずれかの場合に必要な配管

run_gui & 
run_ai1 & 
run_ai2 & 
while true; do 
    while true; do 
     read -u $ai1_outfd line || echo "Nothing read" 
     if [[ $line ]]; then 
      : # processing 
     fi 
    done 
    sleep $turndelay 
    while true; do 
     read -u $ai2_outfd line || echo "nothing read" 
     if [[ $line ]]; then 
      : # processing 
     fi 
    done 
    sleep $turndelay 
done 

を行う、私は彼らの終了コードをチェックして、残りのプロセスを終了します。たとえば、run_ai2が終了コード3で終了する場合は、プロセスrun_ai1run_guiを停止し、終了コード1でメインスクリプトを終了します。異なるバックグラウンドプロセスの正しい終了コードが異なる場合があります。

問題は、どのように検出できますか?コマンドwaitがありますが、どのスクリプトが最初に終了するかは事前にわかりません。私はwaitをバックグラウンドプロセスとして実行することができますが、それはさらに不調です。

お願いします。

+1

トラップSIGCHLDを、それは –

+0

あなたが使用することはできますが終了した子で、いくつかの文を実行することができます[期待](のhttp://期待.sourceforge.net /)? POSIXシェルやBashよりExpectでは、サブプロセスを終了する方がよりエレガントです。 – nwk

+0

@nwk私はbashスクリプトを書いています。だから私はこれが許されることを疑う。 – marmistrz

答えて

2

次のスクリプトは、テスト用の子プロセスを監視します(例では、睡眠+偽と睡眠+真)とそのPID、終了コードを報告します。

#!/bin/bash 

set -m 

trap myhandler CHLD 

myhandler() { 
    echo sigchld received 
    cat /tmp/foo 
} 

(sleep 5; false; echo "exit p1=$?") > /tmp/foo & 
p1=$! 
echo "p1=$p1" 

(sleep 3; true; echo "exit p2=$?") > /tmp/foo & 
p2=$! 
echo "p2=$p2" 

pstree -p $$ 
wait 

結果は次のとおりです。

p1=3197 
p2=3198 
prueba(3196)─┬─prueba(3197)───sleep(3199) 
      ├─prueba(3198)───sleep(3201) 
      └─pstree(3200) 
sigchld received 
sigchld received 
exit p2=0 
sigchld received 
exit p1=1 

SIGCHLDの代わりにSIGUSR1を使用すると面白いかもしれません。例についてはこちらをご覧ください:https://stackoverflow.com/a/12751700/4886927

また、トラップハンドラ内では、どの子がまだ生きているかを確認することができます。

myhandler() { 
    if kill -0 $p1; then 
    echo "child1 is alive" 
    fi 
    if kill -0 $p2; then 
    echo "child2 is alive" 
    fi 
} 

または両方チャイルズを殺すそれらのいずれかが死ぬとき:ような何か

myhandler() { 
    if kill -0 $p1 && kill -0 $p2; then 
    echo "all childs alive" 
    else 
    kill -9 $p1 $p2 
    fi 
} 
+0

これは両方のプロセスが終了するのを待ちます。 2つ目が '(yes; echo" exit p2 = $? ")>/tmp/foo&'だった場合、 'false'コマンドが停止してもスクリプトは停止しません。 – marmistrz

+0

@marmistrz:もちろん、今度は "kill"コマンドや他の子を止めるのに必要なものを追加する時間です。 –

+0

さて、私は「待ち」に集中してはいけません。なぜバックグラウンドプロセスよりも 'SIGCHLD'が多いのでしょうか?コマンドが終了する前にsigc​​hldが受信されるのはなぜですか? – marmistrz

関連する問題

 関連する問題