強制終了する前に一時停止する必要があるスクリプトを実行しています。初めて実行したとき、プロセスの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
強制終了する前に一時停止する必要があるスクリプトを実行しています。
ええと、違います。強制終了する前にスクリプトを一時停止する必要はありません。あなたはいつでもそれを殺すことができます。
初めて実行したとき、プロセスのpidは1つだけです。私はそれを殺して再び実行し、PIDの数が増えていきます。
その後、あなたは実際にそれを殺していません! ./toplog.sh
を実行して一時停止すると、単一のジョブ、つまりjobs
の出力に1行しか作成されません。スクリプト自体が複数のプロセスを作成する場合がありますが、jobs
はスクリプト自体(技術用語ではプロセスグループリーダー)のみを一覧表示します。ますます多くのジョブが表示される場合、それは、強制終了に失敗した古いジョブがまだ表示されていることを意味します。
ジョブの強制終了に失敗した理由は、おそらくジョブが一時停止されているためです。プロセスが中断されると、シグナルに反応できなくなります。中断されたプロセスにシグナルを送信した場合、そのシグナルはプロセスが再開されたときにのみ効果があります。例外は、プロセスを伴わずにカーネルによって直接管理されるシグナルです。そのような例外の1つは、プロセスを再開するシグナル(SIGCONT)が、明らかにプロセスを即座にウェイクアップすることです。例外の別のカテゴリは、要求せずにプロセスを強制終了するシグナルです。これには常にSIGKILLが含まれ、プロセスがそのシグナルのハンドラーを設定していない場合は他のシグナル(SIGINT、SIGHUP、SIGTERM、SIGQUITなど)も含まれます。
kill %1
がジョブ1を強制終了した場合、シェルはジョブが終了したことを通知します。プロセスがSIGTERMのハンドラーを設定している場合、プロセスが一時停止されている間はkill %1
は効果がありません。プロセスを強制終了するには、プロセスを再開する必要もあります。
kill %1; kill -CONT %1
クリーンアップの機会を与えずにプロセスを強制終了したい場合は、
kill -KILL %1
(または略してkill -9 %1
)。
この端末から起動されたかどうかに関係なく、すべてのtoplog.sh
プロセスを強制終了する場合は、pkill toplog.sh
を使用できます。
実行時にプロセスがどのように呼び出されるかがわかっている場合は、スクリプトのすべてのインスタンスを強制終了できます(この例ではtoplog.sh)。
ps x | grep toplog.sh | grep -v grep | cut -d" " -f1 | xargs kill -9
ps xは、ターゲットプロセスからgrepされるすべてのプロセスのリストを提供します。 2番目のgrepは、grep呼び出し自体をリストから削除することを確認します。そうしないと、エラーが発生します(実際にはまだ問題ありませんが、醜いです)。 cut -d "" -f1すべての行をスペース文字で分割された複数の部分に分割し、*-f1 **が最初の部分を取ります。 xargs kill -9以前にコマンドチェーンからスローされたすべてのpidを強制終了します。
便宜上、この行をkillスクリプトに入れると、プロセス名がkillscript引数に置き換えられます。
#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9
次に、強制終了されるプロセスの名前を使用してスクリプトが呼び出されます。
./kill.sh toplog.sh