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


9

環境:

ユーザーは、実行するカスタムスクリプトを提供します。これらのスクリプトは、複数の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 -ef PIDにエントリがなくなるまで待機します。非ブロッキングスクリプトは私に問題を与えるものです

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


親のPIDを取得できない限り、親スクリプトの終了後は可能ではないと思います。スクリプトを起動するpid$(foo.sh; echo $!)場合は、PIDを提供するようなものでそれらをラップしてfoo.sh、を使用できるようにすることができますps --ppid。うまくいきますか?
terdon 2013

2
スクリプトは作成者ユーザーのUIDで実行する必要がありますか?そうでない場合は、この目的のためだけにダミーユーザーを作成できますか?あなたも、必要はありませんgrepだけで、ps –udummy_user。また、プロセスグループも確認してください。
スコット

これは、最初の質問の解決策というよりは一種の回避策です。新しいbashセッションを開きます。ps引数なしで使用することで、このシェルから生成されたすべてのプロセスを一覧表示できます(最初のみbashpsしてください)。そこでスクリプトを開始します。完了したら、ps | wc -l期待値に達するまで待ちます。
Tim

回答:


8

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

jobs -p

すべての子プロセスのリストを提供します。

代替#1

しかし、あなたの場合wait、パラメータなしでコマンドを使用する方が簡単かもしれません:

first_program &
second_program &
wait

これは、すべての子プロセスが終了するまで待機します。

代替#2

別の方法としては$!、最後のプログラムのPIDを取得して変数に蓄積する方法があります。

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

そして、それと一緒にwaitを使用します(これは、子プロセスのサブセットのみを待機したい場合のためです):

wait $pids

代替#3

または、すべてのプロセスが完了するまで待機する場合は、

wait -n $pids

ボーナス情報

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

trap 'kill $(jobs -p)' SIGINT SIGTERM EXIT

1

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

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

(ソースユーザースクリプト;待機)

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

(ソースユーザースクリプト;待機)&待機

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


3
これについても考えましたが、userscriptがバックグラウンドで添え字を開始し、次にバックグラウンドで別のスクリプトを開始すると、このソリューションは失敗します。あなたのwaitコマンドは、その後の子供たちのために待機しますuserscriptその孫のためにではなく。
Tim

@Timは次のことに気づきました:(
irraju 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.