web-dev-qa-db-ja.com

すべてのバックグラウンドプロセスを終了します

Stoppedのバックグラウンドプロセスがいくつかあります。

kill $(jobs -p)およびkill `jobs -p`効果はありません

kill %1kill %2などは、個々のプロセスを正常に終了します

1つのコマンドですべてのバックグラウンドプロセスを強制終了するにはどうすればよいですか?

また、最初の2つのコマンドが機能しないのはなぜですか?

Linux Mint 15、64ビットを実行しています

10
user49888

彼らが走っているとき

killjobs -pの出力でこれを行うことができるようです。

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

現在、3つの偽のジョブが実行されています。

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

そのようにそれらをすべて殺します:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

それらがすべてなくなったことを確認します。

$ jobs
$

彼らが止まったとき

実行されていない、停止されているジョブがある場合は、代わりにこれを実行します。

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK、それは彼らを殺しませんでした、しかしそれは殺害信号がプロセス自体によって処理されることができないので、それは止められます。したがって、代わりに強制終了を行うようにOSに指示してください。それが-9の目的です。

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

それは良いです。

$ jobs
$ 

一部が実行され、一部が停止している場合

一部が停止して一部が実行されているプロセスの混合バッグがある場合は、最初にkillを実行し、次にkill -9を実行できます。

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

プロセスが最初に停止できるようにするためにさらに時間が必要な場合は、時間を少し延長します。

信号

KillするHUP(-1)またはSIGTERM(-15)は成功しません。しかし、なぜ?これは、これらのシグナルが、アプリケーションにそれ自体を終了するように指示しているという意味で、より親切だからです。ただし、アプリケーションは停止状態にあるため、これらの信号を処理できません。したがって、SIGKILL(-9)を使用することだけがコースです。

killkill -lで提供するすべてのシグナルを確認できます。

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

さまざまなシグナルについてさらに詳しく知りたい場合は、シグナルのマンページman 7 signalをご覧になることを強くお勧めします。

10
slm

あなたはこれを試すことができます。

for x in `jobs -p`; do kill -9 $x; done

ただし、プロセスを終了する場合は、次のようにコマンドを発行できます。

for x in `jobs -p`; do kill -15 $x; done

WikiKillコマンドのページから、

プロセスには、[〜#〜] sigterm [〜#〜]シグナルを4つの方法で送信できます(この場合、プロセスIDは「1234」です)。

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

プロセスには、次の3つの方法で[〜#〜] sigkill [〜#〜]シグナルを送信できます。

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

this answerで説明されているように、これはterminatekillの違いです。

終了シグナル[〜#〜] sigterm [〜#〜]は、プログラムで傍受できるシグナルです。多くの場合、バックグラウンドで実行することを意図したプロセスがこのシグナルをキャッチし、シャットダウンプロセスを開始して、正常に終了します。キル信号[〜#〜] sigkill [〜#〜]は傍受できません。これがプロセスに送信されると、そのプログラムは突然終了します。

たとえば、コンピュータをシャットダウンまたは再起動すると、通常、[〜#〜] sigterm [〜#〜]が実行中のプロセスに最初に送信され、クリーンな方法で終了できるようになります。彼らがそれをサポートするなら。次に、数秒後、[〜#〜] sigkill [〜#〜]がまだ実行中のプロセスに送信され、使用中のリソース(ファイルなど)が強制的に解放されます。使用中)、シャットダウンシーケンスを続行できます(ファイルシステムのマウント解除など)。

2
Ramesh

さて、これをいじってみてください。停止している(実行が一時停止されているが終了していない)ジョブを強制終了すると、フォアグラウンドになるまで完了しません。プログラムは通常、を押すと停止します Ctrl-Z 端末上。この場合、ほとんどの端末はSIGSTOPを送信しますが、もちろんkill -STOPkill -19を使用するなど、他の方法で送信することもできます。

SIGTERMによって送信されたデフォルトのkill信号を処理するにはプログラムを実行する必要があるため、プログラムがすぐに終了しないのは正常な動作です。さらに、bashSIGTERMをバックグラウンドプロセスに送信した後、何とか停止してしまうことがあります(SIGTERMはまだ保留中です)。

すべてのジョブを完了するための最も安全な方法(なしkill -9に頼る)は、最初にSIGTERMを通常のkillで送信し、次に送信することですSIGCONT残りのジョブ(例:

kill $(jobs -p)
kill -18 $(jobs -p)

SIGCONT18はシグナル番号)は、停止したジョブをフォアグラウンドに移動して、通常どおりにSIGTERMを処理できるようにします。

すべてのプログラムがこれで終了しない場合は、kill -9に頼る前に、通常はプロセスを終了させるために試すことができる他のいくつかのシグナルがあります。私が最初にお勧めするのはSIGHUPです。これは、通常、他の終了信号をブロックする多くのプログラムがSIGHUPに応答するためです。これは通常、制御端末が閉じるときに送信されます。特に、sshとのttyセッションが終了したときに送信されます。シェルなどの多くの対話型プログラムは、他の終了信号に応答しませんが、sshセッションが終了した後(または制御端末が閉じた後)に実行を継続することが問題になるため、これに応答します。これを試すにはそうすることができます

kill -1 $(jobs -p)
kill -18 $(jobs -p)

もちろん、信号を処理できるように、プログラムが停止していないことを確認する必要があります。試すことができる他の終了信号は、SIGINTkill -2)とSIGQUITkill -3)です。しかしもちろん、全範囲を試すことの利点は減少し、避けられないSIGKILL(別名kill -9)につながる可能性があります。

1
Graeme

これにより、現在のシェル内のすべてのジョブが1つずつ終了します。

while kill %; do :; done

説明: %はリスト内の最後のジョブを参照するため、killがゼロ以外の値を返すまでループします。これは、終了するジョブがこれ以上ないことを意味します。

別のアプローチとしては、最初にSIGTERMを送信し、次にSIGCONTを送信して、ジョブを続行し、最初にSIGTERMを受信する方法があります。

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(何らかの理由で組み込みのkillがおかしいので、ここでは外部のものを使用しました)。

0
dnt