防止 SIGINT 到达子进程

防止 SIGINT 到达子进程

我有一个用于运行服务器的 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,但我不知道为什么这会导致脚本挂起,而不仅仅是导致清理失败。

所以我的问题是:

  1. 为什么这会导致脚本挂起?
  2. 如何防止 SIGINT 到达scpssh进程?

答案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"

相关内容