背景サブシェルを制御する方法は何ですか?

背景サブシェルを制御する方法は何ですか?

Bashプロンプトで次のコマンドを実行すると:

(for i in {1..100}; do echo $i; sleep 1; done) &

計算が開始され、すぐにプロンプ​​トに戻ります。作業を続けることはできますが、毎秒私が作業している項目の上に新しい数字が印刷されます。ジョブが表示されるjobsか、期待どおりに機能しますfgkill

このコマンドを次のスクリプトに移動すると、次のようになりますtest.sh

#!/usr/bin/bash
(for i in {1..100}; do echo $i; sleep 1; done) &

を実行すると./test.sh同じことが起こりますが、ジョブはもう来ず、jobsこれ以上できませんfg。 2番目のアクションが最初のアクションとまったく異なる理由は何ですか?PIDを見つけて終了せずに2番目のアクションをどのように制御できますか?

答え1

$!この目的のためにのみ設定されたPIDを追跡する必要があります。例えば、

#!/usr/bin/bash

(sleep 30; echo "slept for 30 seconds") &
sleeping_pid=$!
# do something
kill $sleeping_pid # or you can wait on it, or...

これは、$!最近開始されたバックグラウンド操作です。したがって、上書きされる傾向があるので、すぐに別の変数にコピーします。

答え2

test.sh私の場合、サブシェルをグループコマンドに変更して目標を達成することができました。

(for i in {1..100}; do echo $i; sleep 1; done) &

~になる

{ for i in {1..100}; do echo $i; sleep 1; done; } &

これにより、すべてのジョブ制御機能を使用できます。幸いなことに、私の目的に応じて、サブシェルとグループコマンドは基本的に同じですが、誰にも適していない可能性があります。

関連情報