SIGINTがサブプロセスに到達するのを防ぎます

SIGINTがサブプロセスに到達するのを防ぎます

通常、ユーザーが使用するサーバーを実行する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

...

現在完了するCtrl-C1秒前に完了すると、scpスクリプトは無期限に中断されます。私はこれがSIGINTbashスクリプトとプロセスに送信することに関連していることを知っていますが、これがクリーンアップにscp失敗するのではなく、スクリプトが中断される理由を知りません。

だから私の質問は次のようになります

  1. これがスクリプトを中断するのはなぜですか?
  2. scpSIGINTがサブプロセスに到達するのを防ぐ方法は何ですかssh

答え1

trap '' INTSIGINT は、シェルとすべての子プロセスを無視するように設計されています。

straceただし、の出力を見ると、上記のSIG_IGNをキャンセルする独自のSIGINTハンドラがインストールされているようscpです。scp

SIGINTの取得を防ぐ唯一の方法は、別のプロセスグループで実行することです。たとえば、次のようになります。

perl -MPOSIX -e 'setpgid 0,0; exec @ARGV' scp...

または

(set -m; scp ... & wait)

stty -isigまたは、後で設定を復元したい場合でも、Ctrl-CでSIGINT転送を停止するようにttyドライバに指示します(例:or aloneを使用)。stty intr ''^C

saved=$(stty -g)
stty intr ''
scp ...
stty "$saved"

関連情報