说我有这两个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信号杀死其进程组。现在,如果我从交互式shell开始将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)
,它会退出整个shell。同样,如果我创建一个调用/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
为什么?
答案 0 :(得分:0)
似乎$()
不使用单独的进程组/ PGID(显然使C-c
工作)启动进程。
此外,任何非交互式shell也不会为其子项启动单独的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
请注意"完成"如果没有打印,那么没有捕获USR1的外部bash脚本会被捕获,而捕获者会一直生存到最后。
您可以将ps -o %p%r%c -p$$
放入,检查每个流程的PGID
脚本:
$ /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
答案 1 :(得分:0)
尝试此更改
的/ 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