バックグラウンドでループが実行されている間にbashを停止する方法は?


23

次のようにwhileループを開始しました。

while true; do {command}; sleep 180; done &

に注意してください&

ターミナルを殺すと、このwhileループが停止すると思いました。しかし、まだ進行中です。ターミナルセッションを終了してから数時間かかりました。

whileループを停止するにはどうすればよいですか?

回答:


38

始めた

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閉じるyadsleep 60、の出力で変更されますps。ツリービューがわかりにくい場合は、次のように出力を検索することもできます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 yadgrepプロセス自体が結果リストに表示されないようにします。


ターミナルがまだ開いている場合

bash変数を提供します$!。これは「最後にバックグラウンドに置かれたジョブのプロセスIDに展開される」ため、以下はバックグラウンドで最新のプロセスを強制終了します。

kill $!

最新のプロセスでない場合は、jobs組み込みの出力サンプルの実行中のジョブのリストを取得できます。

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

2つのジョブは、ジョブ番号またはショートカットでアクセスすることができ、それらの一つ殺すために、ジョブリストであり%%+(「現在のジョブ」)と%-背景あなたにループの実行を殺すために例えば、(「前の仕事を」)出来ました

kill %1  # or
kill %-

中断されたsleep 10ジョブを強制終了するには:

kill %2  # or
kill %+  # or
kill %

5

そのコマンドを入力した端末を閉じると、サブコマンドも一緒に終了することに注意する必要があります。これを再現しようとすると、この動作が示されました。

さて、実際にこれが起こらなかった状況にあると仮定する&と、コマンドの最後で引き起こされたバックグラウンドで実行しているプログラムを強制終了する方法の1つは次のとおりです。

  1. 新しいシェルを開いて実行echo $$し、現在のPID(プロセスID)を書き留めて、自分のセッションを強制終了しないようにします。
  2. まだ実行していると思われるプログラムのPIDを特定します。ps -ef | grep $SHELLコマンドを使用してこれを行うと、どのプログラムがシェルを実行しているかを見つけることができます。
  3. 左から2番目の列に注意し、上記の結果とは異なる数値に注意してくださいecho $$。これは、殺したいPIDです。
  4. kill -SIGTERM <pid>コマンドを実行します。ここ<pid>で、ステップ#3で特定した数値を指定します
  5. 手順2を繰り返して、プログラムが実行されていないことを確認します

セッションまたはコンピューターを再起動することもできますが、上記の方法で回避できます。


2
top押しkてPIDを入力し、Enterを2回押してプロセスを強制終了することもできます。
luk3yx

-1

これ&により、ターミナルは新しいプロセスを作成し、その内部でコードを実行します。したがって、コードは端末プロセスから独立します。ターミナルを閉じても、コードを実行している新たなプロセスは停止しません。したがって、削除する&か実行ps -auxして、プロセスを見つけて強制終了しますkill (process id)


-3

通常、バックグラウンドの場合はbg、フォアグラウンドの場合はfg。あなたが使用している場合は記号の使用はFGには、現在実行中のプログラムが表示されます。強制終了するには、Ctrl + Cを押します。


3
bg/ fgを使用すると、端末がから切り離されると機能しなくなりbashます。子プロセス()があるreptyrため、bashを使用して再接続できませんsleep
xiota

彼はそのプロセスを強制終了するため、端末を閉じました。したがって、次回はfgを使用してプログラムを閉じます。シンプル
好奇心が

@Curiousそれは次回です。しかし、OPはこの時間について尋ねています。
ロンジョン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.