バックグラウンドプロセスが完了し、プロセスIDが逆方向に一致するのを待ちます。

バックグラウンドプロセスが完了し、プロセスIDが逆方向に一致するのを待ちます。

複数のバックグラウンドプロセスをループで実行したいのですが、すべてのプロセスが完了するのを待ちながら、他のバックグラウンドプロセスは続行したいと思います。

waitいくつかの調査の最後に、単一のプロセスIDと逆マッチングするのではなく、必要な各プロセスIDを一覧表示する必要があるソリューションのみを確認しました。似たようなものがあればwait != $pidとても便利です。

スクリプト例:

#!/bin/bash

command1 &
pid=$!
for i in ${array[@]}; do
    for n in $(seq 3); do
        if [ $n -eq 1 ];
            command2 > file &
        else
            command2 >> file &
        fi
    done
done

この例では、すべてのプロセスを一覧表示するためにコマンドを使用する$pid必要がないことを除いて、各プロセスが完了するのを待ちたいと思います。wait可能ですか?

答え1

ただ何か間違っています。

wait

述べたようにhelp wait:

ID(プロセスIDまたはジョブ仕様のいずれか)で識別されたプロセスを待ち、そのプロセスの終了ステータスを報告します。 IDが指定されていない場合は、現在アクティブなすべての子プロセスが待機し、ステータス0が返されます。

「引き続き別のバックグラウンドプロセスを引き続き許可する」としますか?ただdisown。あなたの例に従ってください。

command1 & disown %1
command2 & command2 & command2 &
wait

答え2

他の人が言ったように、プロセスIDが「いいえ」を待つ方法はありません。しかし、このコードパターンは私にとってあまり悪くないようで、あなたが望むことを達成するための提案された方法で提供しています。

これはBash配列を使用し、それをリストとしてコマンドに提供できますwait

はい

サンプルコードの修正版、cmd.bash

!/bin/bash

array[0]=1
array[0]=2

sleep 30 &
pid=$!

pidArr=()
for i in ${array[@]}; do
  for n in $(seq 3); do
    if [ $n -eq 1 ]; then
      sleep 31 > file &
      pidArr+=($!)
    else
      sleep 32 >> file &
      pidArr+=($!)
    fi
  done
done

echo ${pidArr[@]}

sleepこの例では、バックグラウンドで実行できるいくつかの長期実行タスクをシミュレートするためにコマンドを置き換えました。彼らは帯域の役割を果たす以外には何の関係もありません。

最後のコマンドechoも、純粋にforループが完了したときに何が起こるかを確認できます。結局のところ、私たちはwaitそれを実際の命令に置き換えますが、あまりにも先に進むことはありません。

実行例 #1

それでは、プログラムを実行し、何が起こるのかを見てみましょう。

$ ./cmd.bash 
24666 24667 24668

今確認してくださいps

$ ps -eaf|grep sleep
saml     24664     1  0 22:28 pts/9    00:00:00 sleep 30
saml     24666     1  0 22:28 pts/9    00:00:00 sleep 31
saml     24667     1  0 22:28 pts/9    00:00:00 sleep 32
saml     24668     1  0 22:28 pts/9    00:00:00 sleep 32

少し待つと、結局、このすべてが起こります。ただし、これはプロセスIDを配列に追加するとecho後で削除できることを示しています。

例 #2

それでは、その行を変更し、次のようにecho行を変更します。wait

  wait ${pidArr[@]}

これで、変更されたバージョンを実行すると、すべてのプロセスIDを待っていることがわかります。

$ ./cmd.bash 

...約30秒後

$

私たちはヒントを得ます。このように、私たちはすべてのプロセスをうまく待っていました。クイックチェックps

$ ps -eaf|grep sleep
$

だから動作します。

関連情報