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


10

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

kill $(jobs -p)そしてkill `jobs -p`効果はありません

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

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

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

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

回答:


10

彼らが走っているとき

killとの出力でこれを行うことができるようですjobs -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

了解しましたので、それらはkillされませんでしたが、killシグナルはプロセス自体では処理できないため、停止されます。代わりにOSに代わりにkillを実行するように伝えます。それがaの-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)を使うことです。

kill提供されるすべての信号を確認できますkill -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


+最初のプロセスの-シンボルと2番目のプロセスのシンボルがあり、3番目のプロセスにシンボルがないのはなぜですか?
Ramesh 14

私はあなたと同じ結果を得ました。しかし、私はそれを読んだ方が安全なので、のterminate代わりにしたいですkill。を試しましたがkill -15 $(jobs -p)、効果がありませんでした。停止したプロセスはkillすることしかできないが、kill %number(個々の)停止したプロセスは再び終了すると思いました。
user49888 14

@Ramesh +-は、例を設定するときに触れた最後のプロセスです。+任意のコマンドが明示的に含まれていないことを意味し%#、そのコマンドに基づいて行動します。ダッシュ(-)は、私が触れた最後から2番目のコマンドです。
slm

@ user49888-うまくいくkill -9 .. はずです。プロセスは何ですか?それらは消滅したか孤立したプロセスですか?
slm

1
@ user49888-はい、プロセスが何かの途中にあった場合、終了する前にクリーンアップを実行する機会が与えられません。
slm

2

これを試すことができます。

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

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

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

コマンドのWikiページからKill

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

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

プロセスにSIGKILLを送信できます、3つの方法でます。

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

この回答で説明されているように、これは終了との違いです killのです。

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

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


これは、killすべてのバックグラウンドプロセスを実行します。しかし、terminate私はそれがより安全であると信じているので、代わりにそれらへの方法はありますか?
user49888 14

終了したい場合-15は、killコマンドで使用できます。
Ramesh 14

-15ここでも機能しません。私のA.を参照してください
SLM

@Ramesh-最後の2つの段落は正しくありません。SIGTERMは送信されません(最初は送信されません)。プロセスは、サービス停止/開始スクリプトを介して最初に停止しようとします。それが9がプロセスに送信された場合であり、プロセスがOPの例のように停止した場合、kill -9私の例では機能しませんでした。
slm

1

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

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

すべてのジョブを(頼ることなくkill -9)完了するための最も安全な方法は、まずSIGTERMnormal 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)につながる可能性があります。


あなたがそうするならば、man signalあなたはこれをバックアップするために参考資料を得ることができます。
slm

これは、私のAの提案のよりやわらかな形です。私が過去に遭遇したことがあり、これでもまだ完全にクリーンアップされない場合があるため、スクリプトからこれを実行している場合、kill -9 ..メソッドはほとんどの場合に機能します。これは時々プロセスがハングしたままになるので、より多くの時間失敗します。それはあなたが決めなければならないトレードオフです。ヘビーハンドですべてを殺す方が良いです。データ/クリーンアップのリスクは、ソフトクリーンアップよりも危険ですが、キルが次第に厳しくなるにつれて、より多くの分析を行う必要があります。
slm

@slm、kill -9これは単にプログラムを適切にクリーンアップする機会を与えずにプラグを抜くだけなので、可能な限り回避する必要があります。いくつかの選択肢で更新します。
Graeme 14

あなたの味は私が提案したものよりも柔らかく言ったように、それはあなたが何をしようとしているのか、リスクの観点から許容できるかどうかにかかっています。私もあなたの方法を使用しました。どちらも正しいIMOです。またkill ..; sleep <time>; kill -18 ..; スリープ<時間>; kill -9 ... . Basically working up to the -9`。
slm

@slm、これkill -18は、ジョブを停止するのが一般的であるため、使用する必要のあるものです(場合によっては、bash送信前にジョブの実行を停止するようですSIGTERM)。上記で追加したようSIGHUPに、他のプログラムに応答しない多くのプログラムがこれに応答するので、試す価値があります(シェルで試してください)。それを越えて、しかし、はい、それSIGKILLはおそらく避けられないので、それはそれほど価値がないです。
Graeme 14

0

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

while kill %; do :; done

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

別のアプローチは、最初に送信することができSIGTERM、その後、SIGCONTあなたの仕事を続けることができますし、最初のものは、彼らはあなたを受け取るやるのでSIGTERM

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.