サーバーを実行するためのbashスクリプトがあります。これは通常、ユーザーがCtrl-C
を使用して終了します。終了時に、クリーンアップ関数を実行します。これは、2番目の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
...
現時点では、scp
が終了する前の2番目のCtrl-C
により、スクリプトが無期限にハングします。これは、SIGINT
がbashスクリプトとscp
プロセスの両方に送信されることと関係があることを理解していますが、なぜこれが原因でスクリプトがハングするのかではなく、途方に暮れています。クリーンアップが失敗するだけです。
だから私の質問は:
scp
およびssh
子プロセスに到達しないようにするにはどうすればよいですか?trap '' INT
は、シェルとそのすべての子のSIGINTを無視することを目的としています。
しかし、strace
のscp
出力を見ると、scp
が上記のSIG_IGNをキャンセルする独自のSIGINTハンドラーをインストールしているように見えます。
SIGINTを取得しないようにする唯一の方法は、次のような別のプロセスグループで実行することです。
Perl -MPOSIX -e 'setpgid 0,0; exec @ARGV' scp...
または
(set -m; scp ... & wait)
または、後で設定を復元したい場合でも、Ctrl-CでSIGINTの送信を停止するようにttyドライバーに指示します(stty -isig
、またはstty intr ''
のみの場合は^C
など)。
saved=$(stty -g)
stty intr ''
scp ...
stty "$saved"