Bash

防止 SIGINT 到達子程序

  • December 23, 2017

我有一個用於執行伺服器的 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程序?

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"

引用自:https://unix.stackexchange.com/questions/350051