![防止 SIGINT 到达子进程](https://linux22.com/image/107119/%E9%98%B2%E6%AD%A2%20SIGINT%20%E5%88%B0%E8%BE%BE%E5%AD%90%E8%BF%9B%E7%A8%8B.png)
我有一个用于运行服务器的 bash 脚本,该脚本通常由用户使用Ctrl-C
.退出时,它会运行清理功能,我不想被第二次打断Ctrl-C
。
#!/bin/bash
...
function cleanup {
trap '' INT
echo -n " Cleaning up..."
scp $SRV:~/$DIR/server.log . && ssh -t $SRV "rm -rf ~/$DIR"
echo " Finished."
exit 0
}
trap cleanup EXIT
...
目前,完成Ctrl-C
前一秒scp
会导致脚本无限期挂起。我知道这与SIGINT
发送到 bash 脚本和进程有关scp
,但我不知道为什么这会导致脚本挂起,而不仅仅是导致清理失败。
所以我的问题是:
- 为什么这会导致脚本挂起?
- 如何防止 SIGINT 到达
scp
子ssh
进程?
答案1
trap '' INT
旨在忽略 shell 及其所有子进程的 SIGINT。
但是查看strace
上的输出scp
,它看起来像是scp
安装了自己的 SIGINT 处理程序,该处理程序取消了上面的 SIG_IGN。
防止它获取 SIGINT 的唯一方法是在不同的进程组中运行它,例如:
perl -MPOSIX -e 'setpgid 0,0; exec @ARGV' scp...
或者
(set -m; scp ... & wait)
或者告诉 tty 驱动程序停止在 Ctrl-C 上发送 SIGINT(例如单独使用或stty -isig
),尽管您想在之后恢复设置:stty intr ''
^C
saved=$(stty -g)
stty intr ''
scp ...
stty "$saved"