2015-04-15 2 views
2

Я написал сценарий в оболочке и столкнулся с поведением, которое я не совсем понимаю. Именно этот сценарий:Родительский процесс останавливается после приема и захвата сигнала от ребенка?

#!/bin/sh 

# traps SIGINT and only echoes 
trap 'trapINT' INT 
trapINT() { 
    echo "Child calling." 
} 

# sleeps for i seconds, then prints i and 
# sends a SIGINT to parent 
sleep_and_echo() { 
    sleep $1 
    echo $1 
    kill -INT $2 
} 

# Main loop, spawn three children 
for i in $(seq 1 3); do 
    sleep_and_echo $i $$ & 
    echo "Process no. $i with PID $! executed." 
done 

# wait for all the children to finish? 
wait 

echo "Waiting done." 
exit 

Сначала я подумал, что для каждого ребенка, родитель получит SIGINT, будет ловушка не прерывать, а затем будет ждать детей до конца, то отзовется, что его дети закончились и будут закончите сам.

Тем не менее, этот процесс делает странную вещь и, похоже, отказывается от его ожидания после получения первого SIGINT от его первых детей (i = 1). Ниже приведено краткое описание сценария:

[email protected]:~/School/UNIX/8-DU$ ./examp.sh 
Process no. 1 with PID 3904 executed. 
Process no. 2 with PID 3905 executed. 
Process no. 3 with PID 3906 executed. 
1 
child calling 
Waiting done. 
[email protected]:~/School/UNIX/8-DU$ 2 
./examp.sh: 11: kill: No such process 

3 
./examp.sh: 11: kill: No such process 

^C 

Может кто-нибудь объяснить это поведение? Я хотел сделать сценарий, который ждет своих детей, и позволяет одновременно запускать до 1 доллара, получать сигнал, если он заканчивается и запускать другой, но тот факт, что он перестает ждать после того, как ловушка рушила эту мысль.

Спасибо

+0

Я считаю, что 'wait' получает сигнал первого и умирает, а затем передавая сигнал к вашему сценарию (который ловит его и продолжает из, теперь мертв, 'wait'). Я думаю, что в обработчике вам нужно повторно «подождать». Также 'INT' может быть не лучшим сигналом для использования здесь. См. Http://mywiki.wooledge.org/SignalTrap для некоторых деталей. –

+0

Спасибо, решена проблема! :) Также объяснение имеет смысл теперь, когда вы указали на это, прежде чем ждать получения сигнала в первую очередь. Большое спасибо. – AshenCZ

+0

Вы просто 'wait' в обработчике или что-то еще? –

ответ

0

Я не могу найти хорошее описание в Posix документы, но Баш говорит страница руководства:

Когда Баш ждет асинхронной команды через ожидания встроенной команды, прием сигнал, для которого установлен ловушка, приведет к тому, что ожидание приведет к немедленному возврату с статусом выхода более 128, сразу после которого выполняется ловушка.

Таким образом, вы можете повторить ожидание, выполнив:

(exit 129) 
while $? -gt 128; do wait; done 
Смежные вопросы