2016-10-24 4 views
2

Я использую именованные каналы для связи между 3-мя процессами: продюсером, некоторыми читателями и некоторыми авторами. Затем я создал скрипт, который просто запускает весь этот процесс, и мне бы хотелось, чтобы при запуске процесса run.sh или завершении процесса всех детей также были убиты. Сценарий run.sh следующим образом:Как убить все вспомогательные процессы bash-скрипта при его завершении?

#!/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 

Как я могу сделать это работает?

Update 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 

Update 2: reader_one.sh и writer_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 
+0

ли они противятся 'убить -9'? Похоже, что они не умирают до тех пор, пока «производитель.sh» не прекратит свое существование. Что он делает точно? – damienfrancois

+0

Использование 'kill -9' позволяет им оставаться в живых. Они (2 читателя и 2 писателя) ждут данных из трубы – tyranitar

+3

Похоже, что 'reader_one.sh' и' writer_one.sh' создают подоболочки. Вы убиваете их основные процессы, но не подпроцессы. – Barmar

ответ

1

Внушение @Barmar обратился ко мне на правильном пути. Проблема была связана с субоболочкой созданной по конвейеру времени, поэтому я изменил это в writer_one.sh и reader_one.sh

cat to_read | while read line; do 
    read_one $line; 
done 

к этому:

while read line; do 
    read_one $line; 
done < to_read 
Смежные вопросы