bashスクリプトで生成されたすべてのプロセスとバックグラウンドプロセスが完了するのを待つ方法

bashスクリプトで生成されたすべてのプロセスとバックグラウンドプロセスが完了するのを待つ方法

プロセスを終了して待ってから、プロセスが完了するまで生成するために生成したいbashスクリプトの操作ソリューションを見つけて見つけましたが、見つかりませんでした。私はまだLinuxについて多くを学んでいます。

コンテキスト: プロセス FOO が実行中です。プロセスBARはFOOを確認して終了するために使用されます(これら2つのプロセスの内部を制御することはできません)。私ができることは、BARにコマンドを渡して実行することだけです。

この例では、FOO を終了するコマンドを BAR に送信します。これにより、別のプロセスが作成され、バックグラウンドに配置されます。

ターゲット:20個のFOOに対して(BARを介して)シャットダウンを実行し、スクリプトの次の部分を続行する前に、すべてのFOOが死ぬのを待つために20個のコマンドを同時に実行しようとしています。

質問:これまでにできることは、BARが実行されるのを待ってからバックグラウンドプロセスがFOOを終了する前に続けることです。

BAR exit FOO1
BAR exit FOO2
...
BAR exit FOO20
wait
do more stuff

私も試しました

BAR exit FOO1
PID1=$!
BAR exit FOO2
PID2=$!
wait $PID1 $PID2

不運。

答え1

待機中の他のプロセスがない場合は、wait引数なしですべてのバックグラウンド操作が完了するまで待ちます。私はしばしば次のような構造を使用します。

for i in *; do md5sum $i & done
wait

ただし、スクリプトに別のバックグラウンド操作があると中断されますが、サブシェルにラップすることはできます。

(for i in *; do md5sum $i & done; wait) & all_md5sum=$!
...
wait $all_md5sum

答え2

FOO1まず、2つのプロセスのみを使用し、次FOO2のスクリプトで実行したい場合など、より簡単なシナリオを試してみてくださいparent.sh

#!/bin/bash

FOO1 &
pid1=$!

echo "Child PID=$pid1 launched"

FOO2 &
pid2=$!

echo "Child PID=$pid2 launched"

BAR exit FOO1
BAR exit FOO2

echo "Pausing to wait for children to finish..."

wait $pid1
wait $pid2

echo "Children finished, moving on."

これが2FOO秒間動作していることを確認し、その場合は20秒間動作していることを確認してください。

説明する

FOO私たちは内部とプロセスを見ることができないので、あなたが投稿したBARものにのみ依存しており、あなたが言ったことを理解しています

  • 「プロセスBARはFOOを確認して終了するために使用されます。」
  • つまり、クリップを公開する前に、ある時点でFOO1特定の方法で開始してBAR exit FOO1クリップに影響を与えます。

もともと投稿したスニペットでは、次のように作成しました。

BAR exit FOO1
PID1=$!
  • $!最近のバックグラウンドプロセスのキャプチャ
  • しかし、BAR exit FOO1これはバックグラウンドに入るプロセスではありません。あなたが言ったように、BARを使用してFOOを制御する手段です。 「BARはFOOを確認して殺すために使用されます。」
  • したがって、PIDを$!キャプチャする可能性はほとんどありません。FOO1

したがって、FOO*プロセスが実際に開始されるpidをキャプチャする必要があります。たとえば、オールインを実行していてparent.shプロセスが2つしかない場合は、次のようにします。

#!/bin/sh

FOO1 &
pid1=$!

echo "Child PID=$pid1 launched"

FOO2 &
pid2=$!

echo "Child PID=$pid2 launched"
  • Lowercase pid1、一貫性がある限り、元の大文字を使用することもできます。私は、誤った使用環境変数と区別するための慣例として小文字を使用することを好みます。
  • #echoは何が起こっているのかを知るために追跡するためのオプションです。

次に、確認して終了するように要求したコマンドを実行しますFOO1FOO2

BAR exit FOO1
BAR exit FOO2

次に、

echo "Pausing to wait for children to finish..."

wait $pid1
wait $pid2

echo "Children finished, moving on."
  • 繰り返しますが、echosはオプションですが、問題を解決しながら情報を提供し、何が起こっているのかを伝えます。
  • waitみんなのために$pid...
  • 以下は、ingが終わったechoことを知らせる別のオプションです。wait

クレジット取引

2009年撮影無料PDF 506ページの非同期スクリプトの例

答え3

各コマンドのファイルをタッチしてファイルを確認できます。簡単な例は次のとおりです。

#!/usr/local/bin/bash

# Flag to knkow when completed
finished=0;

# The commands t run
declare -a commands=('cmd1' 'cmd2' 'cmd3' 'cmd4');

# Fork all commands
for cmd in "${commands[@]}"; do
        ./$cmd &
done

# Loop to wait for all processes to finish
loop=0;
while [ $finished -eq 0 ]; do
        # Just for visual effect
        loop=$((loop+1));
        echo "Loop $loop";
        sleep 1;

        files=0;
        for cmd in "${commands[@]}"; do
                # Each program shoudl touch a file so that we
                # can know it has completed successfully
                if [ -e ".$cmd" ]; then
                        echo "Process $cmd completed";
                        files=$((files+1));
                else
                        # No need to continue if anything is not done
                        # Error checking here like a TTL value or ps -ef | grep pid etc
                        echo "Waiting for process $cmd";
                        break;
                fi;
        done

        # if we have as many files as executed commands
        if [ "$files" -eq ${#commands[@]} ]; then
                finished=1;
        fi
done;

echo 'All jobs completed successfully';
# Clean up after yourself
for cmd in "${commands[@]}"; do
        rm -f ".$cmd";
done;

次に、各cmd1、cmd2 ... cmdNをテストするには、次のようにします。

#!/usr/local/bin/bash
num=1;

echo "Enter cmd$num";
sleep 1; # use different sleep values to simulate execution
touch ".cmd$num"
echo "Exit cmd$num";

答え4

$ PID1が実行されている場合はtrueと評価されます。 if [kill -s 0 $PID1 ]

if句を複数持つことができます。 PID が実行されていない場合は false と評価されます。この節(他の節と共に)は、必要に応じてスクリプトの流れを制御する必要があります。

関連情報