パイプを介して停止したすべてのプロセスを終了

パイプを介して停止したすべてのプロセスを終了

殺す前に一時停止する必要があるスクリプトを実行しています。初めて実行したとき、プロセスにはPIDが1つしかありませんでした。私はそれを殺して再び実行し、PIDの数が増え続けた。まず、なぜこのような行動が起こるのか?各PIDに明示的に言及せずに停止したプロセスをすべて終了するにはどうすればよいですか?

./toplog.sh

停止する:

Ctrl-Z

保留中のプロセスを一覧表示します。

jobs -l

出力:

[1]  12055 Stopped                 ./toplog.sh
[2]  12752 Stopped                 ./toplog.sh
[3]- 13276 Stopped                 ./toplog.sh
[4]+ 13579 Stopped                 ./toplog.sh

殺す:

kill 12055 12752 13276 13579

答え1

殺す前に一時停止する必要があるスクリプトを実行しています。

ええと、いいえ。終了する前にスクリプトを一時停止する必要はありません。いつでも殺すことができます。

初めて実行したとき、プロセスにはPIDが1つしかありませんでした。私はそれを殺して再び実行し、PIDの数が増え続けた。

それでは実際に殺すことはありません!実行./toplog.shして一時停止すると、1つのジョブのみが生成されます。つまり、出力に1行が生成されますjobs。スクリプト自体は複数のプロセスを生成できますが、スクリプトjobs自体のみが一覧表示されます(技術用語はプロセスグループリーダーです)。ますます多くのタスクが表示される場合は、キャンセルしようとしましたが、成功しなかった以前のタスクがまだ表示されることを意味します。

あなたがこれらの仕事を殺すことができなかった理由は、おそらく彼らが停止したからです。プロセスが一時停止すると、信号に応答できません。一時停止したプロセスにシグナルが送信されると、そのシグナルはプロセスが再開されたときにのみ有効です。例外はカーネルによって直接管理されるシグナルであり、プロセスとは関係ありません。 1つの例外は、プロセスを即座に起動するプロセスを再開する信号(SIGCONT)です。別の例外クラスは、問わずプロセスを終了する信号です。これには、プロセスがその信号のハンドラを設定していない場合は、常にSIGKILLと他の信号(SIGINT、SIGHUP、SIGTERM、SIGQUIT ...)が含まれます。

タスク1を終了すると、kill %1シェルはタスクが終了したことを通知します。プロセスにSIGTERMハンドラが設定されている場合、プロセスは一時停止され、kill %1プロセスの終了中には何も起こらないため、再起動する必要があります。

kill %1; kill -CONT %1

クリーンアップの機会を与えずにプロセスを強制終了するには、次のようにします。

kill -KILL %1

(またはkill -9 %1短縮)。

toplog.shこの端末で起動されたかどうかにかかわらず、すべてのプロセスを終了するには使用できますpkill toplog.sh

答え2

実行時にプロセスがどのように呼び出されたか(この場合はtoplog.sh)、知っていればスクリプトのすべてのインスタンスを終了できます。

ps x | grep toplog.sh | grep -v grep | cut -d" " -f1 | xargs kill -9

pxすべてのプロセスのリストを提供すると、ターゲットプロセスでgrepが実行されます。 2番目のgrepは、grep呼び出し自体がリストから削除されたことを確認します。それ以外の場合はエラーが発生します(実際には大丈夫ですが見苦しいです)。切り取り -d" " -f1各行をスペース文字で区切られた複数の部分に分割します。ここで、*-f1**は最初の部分を占めます。xargs kill -9コマンドチェーンで以前にスローされたすべてのpidを終了します。

便宜上、次の行を終了スクリプトに入れることができます。ここで、プロセス名は終了スクリプトパラメータに置き換えられます。

#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9

その後、終了するプロセスの名前でスクリプトが呼び出されます。

./kill.sh toplog.sh

関連情報