一部の子プロセスが終了すると、シェルスクリプトを終了する

一部の子プロセスが終了すると、シェルスクリプトを終了する

Webサーバーを起動し、いくつかのタスクを実行してから2番目のWebサーバーを起動するBashスクリプトがあります。スクリプトを終了したいです。サーバーがシャットダウンするか、ユーザーがCtrl+と入力すると、両方のサーバーがシャットダウンしますC

私が今持っているものは次のとおりです。

start_server_1 &
server_1_pid=$!

trap "kill $server_1_pid" EXIT

# ...do some work that requires server 1 to be running...

start_server_2 || exit $?

ユーザーがCtrl+を入力すると、両方のサーバーが正しくシャットダウンされますC。ただし、サーバー 1 がシャットダウンすると、サーバー 2 とスクリプト自体は引き続き実行されます。これらのプロセスのいずれかが終了したときにサーバーとスクリプトの両方を終了させるにはどうすればよいですか?

答え1

これら2つのプロセスをバックグラウンドで実行し、wait -nそのうちの1つが終了するのを待ちます。

Bashはどのプロセスが終了したかを報告しませんが、以下を実行できます。jobs -pまだ実行中のバックグラウンドタスクのリストを取得して終了します。

start_server_1 &
server_1_pid=$!
start_server_2 &
server_2_pid=$!
wait -n
kill $(jobs -p)

wait -nBash 4.3の新機能。以前のバージョンでは、これははるかに困難でした。

他の一般的なシェルはそうではありませんが、wait -nSIGCHLDにトラップを設定してプレーンを呼び出すことができますwait。ダッシュ、ksh93、mksh、zsh では作成できます。

trap 'kill $server_1_pid $server_2_pid; exit' CHLD
wait

すべてのジョブの実行が完了するまでSIGCHLDトラップは呼び出されないため、これはbashでは機能しません。

関連情報