2

名前付きパイプを使用して、プロデューサー、一部のリーダー、一部のライターの 3 種類のプロセス間で通信しています。次に、すべてのプロセスを単純に実行するスクリプトを作成しました。run.sh プロセスが強制終了されるか、すべての子プロセスが終了すると、プロセスも強制終了されます。run.sh スクリプトは次のとおりです。

#!/bin/bash
MAX_WRITERS=2
MAX_READERS=2

trap 'jobs -p | xargs kill' EXIT

./producer.sh &
for ((i=1; i<=$MAX_READERS; i++)); do ./reader_one.sh & done
for ((i=1; i<=$MAX_WRITERS; i++)); do ./writer_one.sh & done
wait

スクリプトは非常に単純ですが、いくつかのプロセスが実行されているのがまだ見えるため、機能していないようです (producer.sh が強制終了されただけです)。

$ ./run.sh
... some activities ...
^C
$ ps aux | grep "[b]ash ./"
user         48909   ... /bin/bash ./writer_one.sh
user         48906   ... /bin/bash ./writer_one.sh
user         48904   ... /bin/bash ./reader_one.sh
user         48901   ... /bin/bash ./reader_one.sh

だから私はこれで殺す必要があります:

$ ps aux | grep "[b]ash ./" | awk '{print $2}' | xargs kill

どうすればそれを機能させることができますか?

更新 1: でバックグラウンドで実行されたジョブ&は信号に抵抗できるようです。SIGINTそのため、シンプルkillでは役に立ちません。kill -9またはをトラップ内で使用すると、信号を受信しますが、適切に殺されたkill -TERMだけで、生きたままになります。producer.sh

./run.sh: line 21: 50039 Killed: 9               ./producer.sh
./run.sh: line 21: 50040 Killed: 9               ./reader_one.sh
./run.sh: line 21: 50041 Killed: 9               ./reader_one.sh
./run.sh: line 21: 50042 Killed: 9               ./writer_one.sh
./run.sh: line 21: 50043 Killed: 9               ./writer_one.sh

$ ps aux | grep "[b]ash ./"
user         50069   ... /bin/bash ./writer_one.sh
user         50068   ... /bin/bash ./writer_one.sh
user         50064   ... /bin/bash ./reader_one.sh
user         50061   ... /bin/bash ./reader_one.sh

更新 2: 名前付きパイプでデータを待っているだけですreader_one.shwriter_one.sh

更新 3:read_one.shここに; のコードがあります。おそらくその理由は、パイプの直前にあるため、サブシェルですwhile

init_read(){
...
}

read_one(){
...
}

init_reader
while true; do
  cat to_read | while read line; do
    read_one $line;
  done
done
4

1 に答える 1