2016-08-12 11 views
1

Я запутался в передаче сигналов дочерним процессам с помощью ловушек. Скажем, у меня есть два сценария:bash trap '' vs функция передачи функции ловушки

A.Sh

#!/bin/bash 

# print the process id 
echo $$ 

cleanup() { 
    rv=$? 
    echo "cleaning up $rv" 
    exit 
} 

sleep 5 
trap '' SIGTERM # trap cleanup SIGTERM 
echo 'cant stop wont stop' 
./b.sh 
echo 'can stop will stop' 
trap - SIGTERM 
sleep 4 
echo 'done' 

b.sh

#!/bin/bash 
sleep 4; 
echo 'b done' 

Если я исполняю a.sh, а затем из другого окна убить группу процессов с kill -- -PGID, то SIGTERM игнорируется и не передается по адресу b.sh. Но если я делаю trap cleanup SIGTERM, SIGTERM проходит и заканчивает b.sh. Почему моя ловушка передает сигнал в одном случае, а не в другом?

ответ

1

Это интересно. Цитирование man 7 signal:

Ребенок, созданный с помощью fork (2), наследует копию расположения сигнала родителя. Во время execve (2), расположение обработанных сигналов сбрасывается до значения по умолчанию; расположение игнорируемых сигналов остается неизменным.

В вашем случае ребенок всегда получает TERM благодаря тому, что он находится в той же группе процессов. Проблема в том, что он делает с этим.

Когда родитель игнорируетTERM, по правилу выше, так же как и ребенок, поэтому ребенок выживает. Когда родительский поймаетTERM, обработчик ребенка будет сброшен, и он умрет как действие по умолчанию.

1

От trap man page:

ловушка [условие действия ...]

Если действие равно нулю (""), то оболочка будет игнорировать каждый указанное условие, если оно возникает.

Итак, когда вы выполняете TRAP '' SIGTERM условие SIGTERM игнорируется. Попробуйте использовать значение площади вместо этого и посмотрите, работает ли оно:

sleep 5 
trap ' ' SIGTERM # Note the space (' ')!! 

echo 'cant stop wont stop' 
./b.sh 

echo 'can stop will stop' 
trap - SIGTERM 

sleep 4 
echo 'done'