bash信号陷阱将覆盖其nohup子命令的信号?

时间:2016-07-26 11:40:29

标签: linux bash shell

今天我遇到了一个问题,由shell脚本启动的程序无法接收INT信号。经过一番调查,我将在下面展示我的发现。

这是我想要运行的目标程序,如果您手动启动此程序,我使用gcc hello.c -o hello.out编译它,您可以通过kill -2

停止它
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    while (1) {
        printf("--------Hello Wolrd!\n");
        sleep(2);
    }
    return 0;
}

然后我有一个shell脚本在开始我的程序之前进行一些处理。这是简洁版,我们称之为trap.sh

#!/bin/bash

pid=0

function singal_handler() {
    echo "pid is "$java_pid
}

trap "singal_handler" INT

pid=2

nohup ./hello.out &

while true; do
    echo "running...."
    sleep 2
done

请注意,我使用陷阱来捕获INT信号以完成我自己的工作,并使用hello.out启动nohup

现在我按bash trap.sh启动我的程序。

通过向我的trap.sh发出kill -2,行为是预期的,pid输出已经结束。

令我感到惊讶的是,此时,当我向我的背景kill -2发出hello.out时,hello.out仍在那里,它并没有消失。

所以我正在写这个问题,问为什么会这样。 bash trap将覆盖其子命令的信号处理程序?

我的平台是64位linux:

uname -r -----&gt; 3.10.0-123.el7.x86_64

感谢。

1 个答案:

答案 0 :(得分:3)

bash manual说:

  

当要执行除内置函数或shell函数之外的简单命令时,将在包含以下内容的单独执行环境中调用它。除非另有说明,否则值将从shell继承。

     
      
  • shell的打开文件,以及由重定向到命令
  • 指定的任何修改和添加   
  • 当前工作目录
  •   
  • 文件创建模式掩码
  •   
  • 标记为导出的shell变量和函数,以及为该命令导出的变量,在环境中传递(参见环境)
  •   
  • shell捕获的陷阱被重置为从shell的父级继承的值,并忽略shell忽略的陷阱
  •   

man sigaction说:

  

通过fork(2)创建的子级继承其父级信号处置的副本。在执行(2)期间,处理信号的处置被重置为          默认;被忽略信号的处理方式保持不变。

所以是的,SIGINT得到了忽略,因为父shell忽略了它。