特定の条件が満たされるまでプロセスを再開する非同期whileループがあります。これは次のとおりです。
(while [ "$check_condition" -eq 1 ]; do
./async_command
done) &
... # do some stuff
check_condition=0
pkill -9 async_command
ご覧のとおり、check_condition
0に変更してまだ実行中の非同期プロセスを終了しました。問題は、whileループが実行され続け、プロセスが再起動されることです。
私はループがcheck_condition
開始後にのみ値を登録し、どんな変更も気付かないと思います。
この問題をどのように解決できますか?
答え1
kill $!
バックグラウンドで実行されている最後のプロセスを終了する必要があります。バラよりBashスクリプトで「$!」とはどういう意味ですか?
バックグラウンドで別のコマンドを実行している場合は、そのPIDを変数に保存し、$!
後でそのIDを使用して必要に応じてプロセスを終了できます。
( while ... done ) & pid=$!
それから
kill $pid
または、jobs
実行中のバックグラウンドプロセスを確認し、そのIDを使用して終了します。
kill %Id
また、見ることができますバックグラウンドプロセスを終了するには?
答え2
coproc
名前付きループをシミュレートするために使用されます。
名前付きループに最も近いものはbash
次のとおりですcoproc
。
coproc loop1 { while ((1)) ; do echo a >> aout ; sleep 1 ; done ;}
echo PID of loop1 $loop1_PID
coproc loop2 { while ((1)) ; do echo b >> bout ; sleep 1 ; done ;}
echo PID of loop2 $loop2_PID
coproc loop3 { while ((1)) ; do echo c >> cout ; sleep 1 ; done ;}
echo PID of loop3 $loop3_PID
sleep 2
kill $loop1_PID
sleep 2
kill $loop2_PID
sleep 2
kill $loop3_PID
つまり
coproc NAME simple_command
#or
coproc NAME { series ; of ; commands ;}
PIDは保存され、NAME_PID
後でそれを使用してプロセスを終了できます。
選択する:仮想ファイル
@αГsнιιが提案したPIDを使用するのが最も正しい方法ですが、ここで別のアイデアはダミーファイルを作成することです。
#!/bin/bash
dummy="$(mktemp -u -p .)"
( while [ ! -e "$dummy" ] ; do ./async_command ; done ) &
...
#condition met
touch "$dummy"
...
また、このファイルを条件が満たされたことを示すインジケータとして使用することも、クリーンアップしtrap
たい場合はファイルを追加することもできます。繰り返しますが、PIDによる制御を好む必要がありますが、それを乱用してループに「名前を付け」、正しいループを停止することができます。