如何发出孤立的后台进程信号?

时间:2014-02-01 18:58:47

标签: bash unix signals tcl orphan

我正在从我的tcl脚本执行后台shell脚本。 tcl脚本在一段时间后结束执行。此时我假设后台shell脚本变为orphan并被init采用。

set res [catch { exec sudo $script &}]

现在问题是我无法发出我的(孤儿)背景脚本的信号。但为什么?好的,它现在属于init,但为什么我不能发信号呢。只有sigkill似乎可以工作并杀死它 - 我需要触发我编写的信号处理程序来处理SIGUSR2

trap 'process' SIGUSR2

为什么我不能发出孤儿背景流程的信号?有没有办法做到这一点?或者有一些解决方法吗?

编辑:当不涉及睡眠时似乎工作正常。请参阅以下示例代码:

trap 'kill `cat /var/run/sleep.pid`; foo' SIGUSR2;

foo(){ echo test; }

while true; do
  echo -n .
  sleep 100 &
  echo ${!} > /var/run/sleep.pid
  wait ${!}
done

当没有孤儿时工作正常 - 但在孤儿过程的情况下,我认为问题是睡眠的真正pid被覆盖,当陷阱到来时我无法杀死它。

1 个答案:

答案 0 :(得分:2)

让我们运行一个像这样的小脚本:

bash -c '(trap foo SIGUSR2;foo(){ echo test; };while true; do echo -n .;sleep 1;done) & echo $!'; read

它会分叉一个后台进程,它只运行并输出一些点。它还将输出过程的PID,您可以使用它来检查和发信号。

$ ps -f 19489
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
michas   19489     1  0 23:45 pts/8    S      0:00 bash -c (trap foo SIGUS...

因为在后台运行命令后,forking shell直接死亡,所以该进程现在由init(PPID = 1)拥有。

现在您可以通知进程调用处理程序:

kill -USR2 19489

如果这样做,您会注意到终端上的“测试”输出打印点。

无论是从shell还是tcl启动后台进程都应该没有区别。如果它运行,你可以发送一个信号,如果有一个处理程序,它将被调用。

如果它真的没有回应信号它可能被阻止,等待某事。例如,在sleep或等待某些IO。