今天我遇到了一个问题,由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
感谢。
答案 0 :(得分:3)
当要执行除内置函数或shell函数之外的简单命令时,将在包含以下内容的单独执行环境中调用它。除非另有说明,否则值将从shell继承。
- shell的打开文件,以及由重定向到命令
指定的任何修改和添加- 当前工作目录
- 文件创建模式掩码
- 标记为导出的shell变量和函数,以及为该命令导出的变量,在环境中传递(参见环境)
- shell捕获的陷阱被重置为从shell的父级继承的值,并忽略shell忽略的陷阱
通过fork(2)创建的子级继承其父级信号处置的副本。在执行(2)期间,处理信号的处置被重置为 默认;被忽略信号的处理方式保持不变。
所以是的,SIGINT得到了忽略,因为父shell忽略了它。