Suppose I am running the following example saved as hello.sh
#!/bin/bash
hello() {
echo "hello"
}
trap "hello" INT
sleep 100
echo "end"
and in shell I start hello.sh
. After 1 second I press Ctrl-C
.
Please treat sleep
as any long-run process that I started.
Here are my questions:
- When
SIGINT
is generated, is it delivered tosleep
directly or to the shell script? - If it is the second, can I let
sleep
has a chance to handle theSIGINT
and do not propagate to its parenthello.sh
? - If it is the first, what is the status of
sleep
after thehello
function is finished?
My tests made me feel that the following occurred in order
sleep
started to runhello.sh
received the signal- function
hello
started to run - function
hello
finished echo "end"
started to run- the script exits.
But at which stage the sleep
process exits and because of what (e.g. the SIGINT stopped the sleep
process?)
CodePudding user response:
$ cat foo.sh
_sigint()
{
echo "received SIGINT"
}
trap _sigint INT
sleep 10000
echo "status=$?"
$ bash foo.sh # <-- start foo.sh and then press CTRL-C
^Creceived SIGINT
status=130
Some explanation:
sleep
runs as a child process ofbash
.bash
andsleep
are running in the same process group which is now the foreground process group.When CTRT-C is pressed, it'll generate
SIGINT
and the signal will be sent to all processes in the foreground process group so bothbash
andsleep
will receiveSIGINT
.According to bash manual (can also see
man bash
)If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
So here
bash
would wait forsleep
to be killed (The default SIGINT behavior is to terminate the process. See signal(7)) first and thenbash
runs itsSIGINT
trap.According to bash manaul
The return value of a simple command is its exit status, or
128 n
if the command is terminated by signaln
.The
SIGINT
is 2 (seekill -l
) sosleep
's exit status is128 2=130
.