
実行中のバックグラウンド タスクがいくつかあるとします。ここで、さらに 2 つのバックグラウンド タスクを実行し、最後の 2 つのタスクだけを待機するとします。例:
# long running commands
sleep 60 &
sleep 60 &
# now wait only for these two:
sleep 5 & sleep 5 & wait; echo waited only for the 5s sleeps.
上記のコマンドの結果、echo コマンドは 60 秒間待機します。
自分ができるということがわかっている待機するにはpidまたはjobidを渡しますしかし、プロセスをfor
ループで開始しているため、PID を簡単に取得することはできません。
これを試してみましたが、うまくいきませんでした:
{ sleep 3 & sleep 5 & } wait; echo did not wait :
sleep 10 & { sleep 3 ; sleep 3 ; }& wait %2; echo only wait 3s
追記:この質問はこのより単純な質問。
答え1
サブシェルを開始できます:
{ sleep 20 && echo second output ; }
( sleep 2 & wait && echo first output )
wait
サブシェル内のコマンドはそこでのみ有効になります。
答え2
より簡単な質問に対する @Kusalananda のガイダンスに基づいて、この例を思いつきました。最も簡単な例ではないかもしれませんが...
以下のコードはすべて対話型シェル内にあります。読みにくいので、回答のためにコードをいくつかの部分に分割しました。
bash
バージョン 4.1 およびそれ以前のバージョンでは、!
内の は""
対話型シェルで履歴置換をトリガーすることに注意してください (これはリリース 4.2 で修正されました)。それが私が騙されていたことです。本当に引用符で囲みたい場合は、 を$!
使用できます"$! "
。末尾のスペースにより、履歴置換が開始されなくなります。
unset to_wait;
date;
sleep 3 &
for i in 1 2 3; do
sleep 1 &
# Don't put the ! in "" or you'll get an `event`.
to_wait+=( $! );
done;
wait "${to_wait[@]}";
date;
echo waited 1s for inner processes;
# wait for the rest of the processes (just for illustration)
wait;
date;
echo waited 3s for outer process;