Bashプロンプトで次のコマンドを実行した場合:
(for i in {1..100}; do echo $i; sleep 1; done) &
カウントが開始され、すぐにプロンプトに戻ります。通常どおり作業を続けることができますが、毎秒、作業中のものの上に新しい番号が印刷されます。期待どおり、jobs
とfg
/kill
でジョブを確認できます。
ここで、このコマンドを次のスクリプトに移動すると、test.sh
:
#!/usr/bin/bash
(for i in {1..100}; do echo $i; sleep 1; done) &
./test.sh
を実行すると、同じことが起こりますが、ジョブはjobs
に表示されなくなり、fg
できなくなります。 2番目の動作が最初の動作とまったく異なるのはなぜですか?2番目のジョブを制御するにはどうすればよいですか(PIDを見つけてそのように強制終了する以外)?
その目的のためだけに、$!
に配置されている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...
$!
は最近開始されたバックグラウンドジョブであることに注意してください。そのため、上書きされる傾向があるため、すぐに別の変数にコピーします。
私の特定のケースでは、test.sh
内のサブシェルをグループコマンドに変更することで目標を達成することができました。
(for i in {1..100}; do echo $i; sleep 1; done) &
なりました
{ for i in {1..100}; do echo $i; sleep 1; done; } &
その後、すべてのジョブ制御機能を使用することができました。幸いなことに、サブシェルとグループコマンドはどちらも私の目的では基本的に同等ですが、すべての人に適しているとは限りません。