Linux Bash脚本:无法正确处理SIGTSTP

Linux Bash脚本:无法正确处理SIGTSTP,linux,bash,signals,bash-trap,Linux,Bash,Signals,Bash Trap,我有一个装载和卸载设备的bash脚本,在这两个脚本之间执行一些读取操作。由于设备速度非常慢,脚本大约需要15秒才能完成(装载至少需要5-6秒)。由于将此设备挂起可能会导致其他问题,我不希望此脚本被中断 话虽如此,我可以正确地处理SIGINT(Ctrl+c),但当我尝试处理SIGTSTP(Ctrl+z)时,脚本会冻结。这意味着信号被捕获,但处理程序没有运行 #!/bin/sh cleanup() { # Don't worry about unmounting yet. Just chec

我有一个装载和卸载设备的bash脚本,在这两个脚本之间执行一些读取操作。由于设备速度非常慢,脚本大约需要15秒才能完成(装载至少需要5-6秒)。由于将此设备挂起可能会导致其他问题,我不希望此脚本被中断

话虽如此,我可以正确地处理SIGINT(Ctrl+c),但当我尝试处理SIGTSTP(Ctrl+z)时,脚本会冻结。这意味着信号被捕获,但处理程序没有运行

#!/bin/sh
cleanup()
{
    # Don't worry about unmounting yet. Just checking if trap works.
    echo "Quitting..." > /dev/tty
    exit 0
}
trap 'cleanup' SIGTSTP
...

我必须手动向进程发送终止信号。知道为什么会发生这种情况以及我如何修复它吗?

在当前执行的进程终止之前,shell不会执行陷阱。(至少,这是bash 3.00.15的行为)。如果通过^c发送SIGINT,则会将其发送到前台进程组中的所有进程;如果当前执行的程序接收到它并终止,那么bash可以执行陷阱。与通过^z的SIGTSTP类似;bash接收到该信号,但在正在运行的程序终止之前不会执行陷阱,如果采用默认行为并挂起,则不会执行该操作。尝试用一个简单的
读取f
替换
,注意陷阱会立即执行。

这很有意义。因此,听起来好像除非您使用脚本执行的所有二进制文件也以您的方式处理^z,否则无法正确处理^z。是这样吗?您可以在setsid下异步运行作业并等待它。例如:
setsidcmd&wait
而不仅仅是
cmd
。似乎可以做到这一点。谢谢你的帮助!但奇怪的是,进程在新会话下不会仍然停止吗?如果cmd是在setsid下启动的,它不会收到^z@January生成的SIGTSTP。当按下ctrl-c时,当前运行的进程和脚本都会收到SIGINT。当前运行的进程终止,然后脚本执行陷阱。键入^z时,SIGTSTP同时发送到脚本和当前进程,因此当前进程将挂起,脚本将挂起等待它。键入
kill-20
发送SIGTSTP时,只有脚本接收信号。