В моем вызываемом скрипте "trap 'echo ignore' USR1", почему вызывающий скрипт убивается?
Скажем, у меня есть два сценария bash:
/ TMP / ловец:
#!/bin/bash
trap 'echo trapper: ignoring USR1' USR1
"$(dirname $0)"/usr1er & p=$!
sleep 1
echo trapper: now killing usr1er
kill $p
echo trapper: sleeping
sleep 1
echo trapper: reached end of trapper
/ TMP / usr1er:
#!/bin/bash
trap 'echo "usr1er: EXIT received, sending USR1"; kill -USR1 0' EXIT
while sleep 1;do echo usr1er: sleeping;done
trapper должен перехватывать USR1 и просто игнорировать его. Он запускает usr1er, который убивает свою группу процессов сигналом USR1. Теперь, если я запускаю trapper как скрипт самостоятельно из интерактивной оболочки, он убивает usr1er и завершается нормально:
$ /tmp/trapper; echo done
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
/tmp/trapper: line 9: 16596 Terminated "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper
done
Хотя если я попробую $(/tmp/trapper)
Выходит из всей оболочки. Точно так же, если я сделаю отдельный скрипт, который вызывает /tmp/trapper
, лайк /tmp/outer
:
#!/bin/bash
"$(dirname $0)"/trapper
echo outer: reached end of outer
его убивают, не печатая "достигнутый конец внешнего":
$ /tmp/outer
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
/tmp/trapper: line 9: 23544 Terminated "$(dirname $0)"/usr1er
User defined signal 1
trapper: ignoring USR1
trapper: reached end of trapper
Зачем?
2 ответа
Попробуйте это изменение
/ TMP /usr1er:
#!/bin/bash
trap 'echo "usr1er: EXIT received, sending USR1"; kill -USR1 $PPID' TERM
while sleep 1;do echo usr1er: sleeping;done
Обрабатывается сигнал TERM вместо EXIT и отправляется USR1 $PPID
вместо 0
Кажется, что $()
не запускает процесс с отдельной группой процессов / PGID (очевидно, для создания C-c
Работа).
Кроме того, любая неинтерактивная оболочка также не будет запускать отдельные PGID для своих детей (если вы не включите управление заданиями с помощью команды set -m):
$ bash -c '/tmp/trapper;echo done'
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
$ /tmp/trapper: line 9: 17522 Terminated "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper
Обратите внимание, что "done" не печатается, внешний bash-скрипт, который не перехватывает USR1, убивается, пока trapper продолжает жить до конца.
Вы можете проверить PGID каждого процесса, поставив ps -o %p%r%c -p$$
в скриптах:
$ /tmp/outer
PID PGID COMMAND
27630 27630 outer
PID PGID COMMAND
27633 27630 trapper
PID PGID COMMAND
27635 27630 usr1er
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
$ /tmp/trapper: line 9: 27635 Terminated "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper