1

実行中のシェルを強制終了せずにシェル関数を非対話的に終了する方法はありますか?

シグナル (例: ) に応答する方法をシェルに指示できることはわかっていますがUSR1、シグナル ハンドラーが関数を終了する方法がわかりません。

必要に応じて、終了する関数が「終了可能」になるように (つまり、いくつかの適切なオプションを宣言することによって) 記述されていると想定することができます。

(私の直接の関心は、 に対してこれを行う方法ですが、および に対してzsh行う方法にも興味があります。)bash/bin/sh

編集: ロブ ワットの提案に応えて:

% donothing () { echo $$; sleep 1000000 }
% donothing
47139

この時点でCtrl-C、シェルを実行しているのと同じ端末でヒットすると、関数donothingは実際に終了し、コマンド プロンプトが返されます。しかし、代わりに、別のシェルセッションから実行すると、

% kill -s INT 47139

...donothing関数は終了しません。

4

1 に答える 1

1

多分私はあなたが何を望んでいるのか完全には理解していませんが、多分このようなものですか?

trap "stopme=1" 2

function longcycle() {
    last=$1
    for i in 1 2 3 4 5 
    do
        [ ! -z "$stopme" ] && return
        echo $i
        sleep 1
    done
}

stopme=""
echo "Start 1st cycle"
longcycle
echo "1st cycle end"

echo "2nd cycle"
stopme=""
longcycle
echo "2nd cycle end"

上記はbash用です。それを実行し、CTRL-C を押してみてください。

またはnot interactively、上記を例として保存してからmy_command、次を試してください。

$ ./my_command &  #into background
$ kill -2 $! #send CTRL-C to the bg process

編集:

sleepbash での例の解決策:

$ donothing() { trap '[[ $mypid ]] && trap - 2 && kill $mypid' 0 2; sleep 1000000 & mypid=$!;wait; }
$ donothing

別の端末からシグナルを送信すると、シグナルが終了します。覚えておいてください、信号「0」は「プロセスの正常終了」です。セマンティック名: 0=EXIT、2=INT... など

また、シグナルが関数ではなくプロセスに送信されていることも覚えておいてください。あなたの例では、プロセスは現在(インタラクティブシェル)であるため、待機トリックを使用して割り込み可能なものを取得する必要があります...良い解決策ではありませんが、インタラクティブシェルで実行されているものに割り込みたい場合の唯一の方法(そうではありません)分岐したもの) 別の端末から...

于 2013-04-03T19:58:20.233 に答える