Bash
防止 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
程序有關,但我不知道為什麼這會導致腳本掛起,而不僅僅是導致清理失敗。所以我的問題是:
- 為什麼這會導致腳本掛起?
- 如何防止 SIGINT 到達
scp
子ssh
程序?
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"