次のようにwhileループを開始しました。
while true; do {command}; sleep 180; done &
&
に注意してください。
ターミナルを殺すと、このwhileループが停止すると思いました。しかし、まだ進行中です。ターミナルセッションを終了してから数時間かかりました。
Whileループを停止するにはどうすればよいですか?
始めた
while true; do yad; sleep 60; done &
そして、それをテストするために端末を閉じましたが、今は同じ問題が発生しました。
ps fjx
を使用して実行中のプロセスの概要を取得しましょう。私のマシンの最後の行は
2226 11606 11606 19337 ? -1 S 1000 0:00 \_ /bin/bash
11606 22485 11606 19337 ? -1 S 1000 0:00 | \_ sleep 10
2226 9411 9411 8383 ? -1 S 1000 0:00 \_ /bin/bash
9411 17674 9411 8383 ? -1 Sl 1000 0:00 \_ yad
1 2215 2215 2215 ? -1 Ss 1000 0:00 /lib/systemd/systemd --user
2215 2216 2215 2215 ? -1 S 1000 0:00 \_ (sd-pam)
yad
を/bin/bash
のサブプロセスとして見ることができます。yad
を閉じると、ps
の出力でsleep 60
に変わります。ツリービューがわかりにくい場合は、次のように出力を検索することもできます1:
ps fjx | grep "[y]ad" # or respectively
ps fjx | grep "[s]leep 60"
出力行は2つの番号で始まります。最初の番号はPPID(親プロセスのプロセスID)で、2番目の番号はPID(プロセス自体のID)です。これは、9411
が両方の行に表示されるためです。
2226 9411 9411 8383 ? -1 S 1000 0:00 \_ /bin/bash
9411 17674 9411 8383 ? -1 Sl 1000 0:00 \_ yad
それが、私たちが殺したいbash
サブシェルであり、PIDを見つけたので、残っているものはすべてシンプルです
kill 9411 # replace 9411 with the PID you found out!
迷惑なサブシェルは永久に消えてしまいました。
1:単にgrep "[y]ad"
の代わりにgrep yad
としての表記により、grep
プロセス自体が結果リストに表示されなくなります。
bash
は、変数$!
を提供します。これは、「最後にバックグラウンドに置かれたジョブのプロセスIDに展開される」ため、次のようにバックグラウンドで最新のプロセスを強制終了します。
kill $!
not最新プロセスの場合、jobs
ビルトインを使用して実行中のジョブのリストを取得できます。出力例:
[1]- Running while true; do
yad; sleep 60;
done &
[2]+ Stopped sleep 10
ジョブリストには2つのジョブがあり、そのうちの1つを削除するには、ジョブ番号またはショートカット%
、%+
(「現在のジョブ」)および%-
(「前の仕事」)、たとえばバックグラウンドで実行されているループを強制終了するには
kill %1 # or
kill %-
中断されたsleep 10
ジョブを強制終了するには:
kill %2 # or
kill %+ # or
kill %
そのコマンドを入力したターミナルを閉じると、サブコマンドも一緒に停止することに注意してください。これを再現しようとすると、この動作が示されました。
さて、あなたが実際にこれが起こらなかった状況にあると仮定すると、コマンドの最後の&
によって引き起こされた、バックグラウンドで実行しているプログラムを強制終了する方法の1つは、次のように:
echo $$
を実行し、現在のPID(プロセスID)を記録して、自分のセッションを強制終了しないようにします。ps -ef | grep $Shell
コマンドを使用してこれを実行し、シェルを実行しているプログラムを見つけることができます。echo $$
の結果からdiffersとなる数値に注目してください。これは、殺したいPIDです。kill -SIGTERM <pid>
コマンドを実行します。<pid>
は、ステップ#3で特定した数値です。セッションまたはコンピューターを再起動することもできますが、上記の方法で回避できます。