web-dev-qa-db-ja.com

スクリプトによって生成されたすべての子プロセスのリストを取得する方法

コンテキスト:

ユーザーは、実行するカスタムスクリプトを提供してくれます。これらのスクリプトは、複数のGUIプログラム、バックエンドサービスを開始するためのスクリプトのようなものにすることができます。スクリプトの記述方法を制御することはできません。これらのスクリプトはブロッキングタイプにすることができます。つまり、すべての子プロセス(順次実行されるプログラム)が終了するまで実行が待機します。

#exaple of blocking script
echo "START"
first_program 
second_program 
echo "DONE"

または非ブロッキングタイプ、つまり、バックグラウンドで子プロセスをフォークし、次のようなものを終了するタイプ

#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"

何を達成しようとしているのですか?

ユーザー提供のスクリプトは、上記の2つのタイプのいずれか、または両方の組み合わせにすることができます。私の仕事は、スクリプトを実行し、スクリプトによって開始されたすべてのプロセスが終了するまで待ってから、ノードをシャットダウンすることです。ブロッキングタイプの場合、ケースは単純です。つまり、スクリプト実行プロセスのPIDを取得し、ps -ef | grep -efPIDにエントリがなくなるまで待ちます。ノンブロッキングスクリプトは私に問題を与えるものです

スクリプトの実行によって生成されたすべての子プロセスのPIDのリストを取得する方法はありますか?ポインタやヒントは高く評価されます

9
irraju

あなたの応答をありがとうみんな..私はstackoverflowの解決策を得ました

Waitを使用して、userscriptによって開始されたすべてのバックグラウンドプロセスが完了するのを待つことができます。待機は現在のシェルの子でのみ機能するため、別のプロセスとして実行するのではなく、スクリプトをソースにする必要があります。

(ソースuserscript;待機)

明示的なサブシェルでスクリプトを調達することで、新しいプロセスの開始を十分にシミュレートする必要があります。そうでない場合は、サブシェルをバックグラウンドで実行して、新しいプロセスを強制的に開始し、完了するのを待つこともできます。

(source userscript; wait)&wait

@chepnerによる元の回答へのリンクは次のとおりです: https://stackoverflow.com/questions/18663196/how-to-get-list-of-all-child-process-spawned-by-a-script/18663969?noredirect = 1#18663969

1
irraju

質問に直接答えるには、コマンド

jobs -p

すべての子プロセスのリストが表示されます。

代替案#1

ただし、あなたの場合は、パラメータなしでコマンドwaitを使用する方が簡単な場合があります。

first_program &
second_program &
wait

これは、[〜#〜] all [〜#〜]子プロセスが終了するまで待機します。

代替案#2

もう1つの方法は、$!を使用して最後のプログラムのPIDを取得し、次のように変数に累積することです。

pids=""
first_program &
pids="$pids $!"
second_program &
pids="$pids $!"

次に、それとともにwaitを使用します(これは、子プロセスのサブセットのみを待機する場合です)。

wait $pids

代替案#3

または、[〜#〜] any [〜#〜]プロセスが終了するまでのみ待機したい場合は、

wait -n $pids

ボーナス情報

Bashスクリプトにsigtermを使用して子プロセスも閉じる場合は、次のような信号を伝播する必要があります(プロセスを開始する前に、これを上部のどこかに配置します)。

trap 'kill $(jobs -p)' SIGINT SIGTERM EXIT
8
Vlad A Ionescu