我在调用的脚本中有“陷阱”echo忽略'USR1',为什么调用脚本会被杀死?

时间:2014-02-20 13:09:09

标签: bash process process-group

说我有这两个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

为什么?

2 个答案:

答案 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