正如我在f01的注释中提到的,您应该将SIGTERM发送到子进程。以下是一些脚本,这些脚本显示了如何捕获^ C并将信号发送到子进程。
首先,父母。
陷阱测试
#!/bin/bash
# trap test
# Written by PM 2Ring 2014.10.23
myname=$(basename "$0")
child=sleeploop
set_trap()
{
sig=$1
msg="echo -e \"\n$myname received ^C, sending $sig to $child, $pid\""
trap "$msg; kill -s $sig $pid" SIGINT
}
trap "echo \"bye from $myname\"" EXIT
echo "running $child..."
./$child 5 &
pid=$!
# set_trap SIGINT
set_trap SIGTERM
echo "$child pid = $pid"
wait $pid
echo "$myname finished waiting"
现在,孩子。
睡眠循环
#!/bin/bash
# child script for traptest
# Written by PM 2Ring 2014.10.23
myname=$(basename "$0")
delay="$1"
set_trap()
{
sig=$1
trap "echo -e '\n$myname received $sig signal';exit 0" $sig
}
trap "echo \"bye from $myname\"" EXIT
set_trap SIGTERM
set_trap SIGINT
#Select sleep mode
if false
then
echo "Using foreground sleep"
Sleep()
{
sleep $delay
}
else
echo "Using background sleep"
Sleep()
{
sleep "$delay" &
wait $!
}
fi
#Time to snooze :)
for ((i=0; i<5; i++));
do
echo "$i: sleeping for $delay"
Sleep
done
echo "$myname terminated normally"
如果traptest发送SIGTERM,则一切正常,但是如果traptest发送SIGINT,则sleeploop永远不会看到它。
如果sleeploop捕获SIGTERM,并且睡眠模式为前台,那么它只有在从当前睡眠中唤醒后才能响应该信号。但是,如果睡眠模式是背景,它将立即响应。
set -m
。它比setsid
每次生孩子时都要使用的清洁和简单。