複数のバックグラウンドプロセスをループで実行したいのですが、すべてのプロセスが完了するのを待ちながら、他のバックグラウンドプロセスは続行したいと思います。
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
$
だから動作します。