我有一个bash shell脚本S1
,可以同步启动另一个shell脚本S2
(仅包含sleep 20
),即在前台。
我想要的是以下内容:
当我向S1
发送SIGTERM或SIGINT时,S1
和S2
都应该停止。
实际上,如果我在前台命令行启动S1
,如果按CTRL-C(无论是否在脚本中明确地捕获SIGINT),这都有效。
当我在后台启动S1
然后向其发送带有kill -s SIGINT $!
的SIGINT信号时,直到S2
终止其正常处理,即S2
不会被中断。
我的用例是后者,我需要通过向S1
发送信号来中断S2
和S1
。
答案 0 :(得分:2)
S1.sh:
#!/bin/sh
on_term()
{
echo "S1: Sending TERM to S2.sh"
pkill -TERM S2.sh
echo "S1: Waiting for S2 to complete..."
}
trap "on_term" TERM
echo "S1: Forking a child..."
./S2.sh &
while [ 1 == 1 ]; do
wait
if [ $? -eq 0 ]; then
break
fi
done
echo "S1: Done!"
S2.sh:
#!/bin/sh
on_term()
{
echo "S2: Terminating..."
exit -1
}
trap "on_term" TERM
echo "S2: Sleeping..."
sleep 5
echo "S2: Done!"
玩得开心!
答案 1 :(得分:2)
如果从命令行启动S1
,则使用以%开头的作业规范将信号发送到流程组中的所有流程,例如kill -INT %+
。
如果您从其他脚本S1
开始S3
,则可能会在S1
上以S2
和SIGINT
终止,这会减少到上述内容。否则,您可以尝试使用
set -m
S1 &
set +m
pid=$!
...
kill -INT -- -$pid
但是对于所有shell,或者如果没有控制终端,这可能无法可靠地工作。如在Ilya的答案中手动转发信号是另一种选择。