如何在同步执行期间处理bash中的信号?

Bro*_*Cat 6 bash signals

我有一个bash脚本进程,它在某些时候同步执行一个长时间运行的子进程.在该子进程的运行期间,信号被直接发送到bash脚本进程,请求脚本终止.有没有办法拦截该信号,终止子进程,然后退出bash进程?

显然,bash的信号处理从不中断同步调用?

我无法控制终止信号被发送到bash进程的事实.虽然如果信号可以传播到子进程,那也可以解决我的问题.

提前谢谢,布鲁斯

tzp*_*tzp 7

请参阅bash的手册页,SIGNALS一章:

如果bash正在等待命令完成并收到已设置陷阱的信号,则在命令完成之前不会执行该陷阱.当bash通过wait builtin等待异步命令时,接收到已设置陷阱的信号将导致wait builtin立即返回,退出状态大于128,之后立即执行陷阱.

因此,异步运行外部程序并使用wait.使用$!杀死它.


Nej*_*ejc 0

是的,可以用命令拦截信号trap。请参阅下面的示例:

#!/bin/bash
function wrap {
local flag=0
trap "flag=1" SIGINT SIGTERM
xeyes &
subppid=$!

while : 
    do
        if [ $flag -ne 0 ] ; then
            kill $subppid
            break 
        fi
            sleep 1        
    done
}
flag=0
trap "flag=1" SIGINT SIGTERM
wrap &
wrappid=$!
while :                 # This is the same as "while true".
    do
        if [ $flag -ne 0 ] ; then
            kill $wrappid
            break
        fi
        sleep 1        # This script is not really doing anything.
done
echo 'end'
Run Code Online (Sandbox Code Playgroud)

基本上trap所做的就是执行“”之间的命令。所以这里的main函数就在下面的while循环中。在每次迭代中,脚本都会检查该标志是否已设置,如果没有,它会休眠一秒钟。在此之前,我们通过 记住了子进程的pid $!SIGINT当或被捕获时,陷阱会发出命令SIGTERM(其他信号请参阅kill手册)。

包装函数的作用与主函数相同。此外,它还调用实际subprocess函数(在本例中,子进程是xeyes)。当包装函数SIGTERM从主函数接收到信号时(主函数也捕获了其中一个信号),包装函数可以在实际杀死子进程之前清理一些东西。之后,它脱离 while 循环并退出包装函数。然后 main 函数也会中断并打印'end'

编辑:希望我正确理解这一点,你被迫执行xeyes &. 那么步骤如下(在终端中):

xeyes &
subpid=$!
trap "kill $subpid && exit " SIGINT SIGTERM
.... other stuff
.... more stuff
^C #TERMINATE - this firstly kills xeyes and then exits the terminal
Run Code Online (Sandbox Code Playgroud)