Ctrl + Cを押すと、シェルスクリプトでバックグラウンドプロセスが完了するまでどのように終了して待ちますか?

Ctrl + Cを押すと、シェルスクリプトでバックグラウンドプロセスが完了するまでどのように終了して待ちますか?

Ctrlcバックグラウンドプロセスを実行してシェルスクリプトを使用するときは、サブプロセスを終了してから終了するようにシェルスクリプトを設定しようとしています。

私が考えることができる最善はこれです。kill 0 -INT待機が発生する前にスクリプトも終了するように見えるため、シェルスクリプトは子プロセスが完了する前に終了します。

このシェルスクリプトが送信された後に子が死ぬのを待つ方法についてのアイデアはありますかINT

#!/bin/bash
trap 'killall' INT

killall() {
    echo "**** Shutting down... ****"
    kill 0 -INT
    wait # Why doesn't this wait??
    echo DONE
}

process1 &
process2 &
process3 &

cat # wait forever

ベストアンサー1

あなたのkill命令は逆さまです。

多くのUNIXコマンドと同様に、マイナス記号で始まるオプションは他のパラメータの前に表示する必要があります。

書くなら

kill -INT 0

-INTオプションとして処理されSIGINT(現在のプロセスグループ内のすべてのプロセスを表す特殊番号)0に送信されます。0

しかし、書いてみると

kill 0 -INT

を表示し、0オプションがないと判断してSIGTERMデフォルト値を使用します。そして送るそれあなたがそうであったように、現在のプロセスグループに

kill -TERM 0 -INT    

SIGTERM(また、送信しようとする-INTと構文エラーが発生しますが、最初に送信SIGTERMして0それ以上到達しません。)

したがって、デフォルトのスクリプトをSIGTERM実行するwait前とecho DONE

次へ追加

trap 'echo got SIGTERM' TERM

トップ、すぐ後ろに

trap 'killall' INT

それを証明するために再実行しました。

Stephane Chazelasが指摘したように、背景がある子供は基本的に無視されprocess1ます。SIGINT

とにかく過ごす方がSIGTERM合理的だと思います。

結局、kill -process group子どもたちに先にあげると言うことはできないようです。ドアを閉めるときは、信号を無視することをお勧めします。

だからこれを試してみてください:

#!/bin/bash
trap 'killall' INT

killall() {
    trap '' INT TERM     # ignore INT and TERM while shutting down
    echo "**** Shutting down... ****"     # added double quotes
    kill -TERM 0         # fixed order, send TERM not INT
    wait
    echo DONE
}

./process1 &
./process2 &
./process3 &

cat # wait forever

おすすめ記事