Today I've encountered one problem, the program that is started by a shell script can not receive INT signal. After some investigating, I will show my findings below.
This is the target program that I want to run, I compile it using gcc hello.c -o hello.out
if you manually start this program, you can stop it by kill -2
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
while (1) {
printf("--------Hello Wolrd!\n");
sleep(2);
}
return 0;
}
Then I have a shell script which does some processing before start my program. Here is the concise version, let's call it 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
Notice that I use trap to capture the INT signal to do my own work, and start my hello.out
using nohup
.
Now I start my program by bash trap.sh
.
By issuing kill -2
to my trap.sh, the behavior is expected, that pid output is out.
What surprises me is that, at this time, when I issue kill -2
to my background hello.out
, hello.out
is still there, it does not vanish.
So I am writing this question to ask why this will happen. The bash trap
will override the signal handler of its subcommands?
My platform is 64bit linux:
uname -r
-----> 3.10.0-123.el7.x86_64
Thanks.
The bash manual says:
When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell.
- the shell’s open files, plus any modifications and additions specified by redirections to the command
- the current working directory
- the file creation mode mask
- shell variables and functions marked for export, along with variables exported for the command, passed in the environment (see Environment)
- traps caught by the shell are reset to the values inherited from the shell’s parent, and traps ignored by the shell are ignored
man sigaction
says:
A child created via fork(2) inherits a copy of its parent's signal dispositions. During an execve(2), the dispositions of handled signals are reset to the default; the dispositions of ignored signals are left unchanged.
So yes, the SIGINT get's ignored because the parent shell ignores it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With