
強制終了する前に一時停止する必要があるスクリプトを実行しています。初めて実行したとき、プロセスの 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
追伸ターゲット プロセスが grep されるすべてのプロセスのリストが表示されます。2 番目の grep は、リストから grep 呼び出し自体を削除することだけを確認します。そうしないと、エラーが発生します (実際には問題はありませんが、見苦しいです)。カット -d" " -f1各行をスペース文字で区切られた複数の部分に分割し、*-f1** は最初の部分を取得します。xargs キル -9以前にコマンド チェーンからスローされたすべての pid を強制終了します。
便宜上、この行を kill スクリプトに入れて、プロセス名を kill スクリプトの引数に置き換えることができます。
#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9
次に、終了するプロセスの名前を指定してスクリプトが呼び出されます。
./kill.sh toplog.sh