SIGINTが子プロセスに到達しないようにする


4

サーバーを実行するためのbashスクリプトがあります。これは通常、ユーザーがを使用して終了しますCtrl-C。終了時にクリーンアップ関数を実行しますが、これは1秒で中断されることはありません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-Cscpが終了する1秒前にスクリプトが無期限にハングします。これはSIGINTbashスクリプトとscpプロセスの両方に送信されることと関係があることは理解していますが、クリーンアップが失敗するだけでなく、これによりスクリプトがハングする原因については迷っています。

だから私の質問は:

  1. なぜこれによりスクリプトがハングするのですか?
  2. どのように私は達することからSIGINTを防ぐことができますscpし、ssh子プロセスを?

実行が行末に達することはありません。scp ...スクリプトechoが呼び出される前にスクリプトがハングします。そして、set -xどのコマンドが呼び出されるかを示すと、&& ssh ...パーツも呼び出されないことがわかります。
フィドー

回答:


7

trap '' INT シェルとそのすべての子のSIGINTを無視することを意図しています。

しかし、上のstrace出力を見ると、上のSIG_IGNをキャンセルする独自のSIGINTハンドラーをインストールしているscpように見えscpます。

SIGINTを取得しないようにする唯一の方法は、次のような別のプロセスグループで実行することです。

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

または

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

または、Ctrl キーを押しながらC キーを押すとstty -isig(またはstty intr ''^C単独で)SIGINTの送信を停止するようにttyドライバーに指示しますが、後で設定を復元します。

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

どうもありがとう。私にとっては、別のプロセスグループで実行するのが効果的です。まだぶら下がっていた理由はscp
わかり
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.