web-dev-qa-db-ja.com

kill 0は実際には何をしますか?

man pageには次のように書かれています:

kill [ -s signal | -p ] [ -a ] [ -- ] pid ...
 pid... Specify the list of processes that kill should signal.  Each pid can be one of five things:
          0      All processes in the current process group are signaled

そして私はこのようにbashで試しました:

$ man kill &
[1] 15247
$
[1]+  Stopped                 man kill
$ kill 0
$ ps
15247 pts/41   00:00:00 man

ここでは、0pidとして使用しています。私が理解したように、kill 0pid15247を含む現在のプロセス内のすべてのプロセスを強制終了します。ただし、この例では何もしませんでした。誰かがそれを使用する方法についてのアイデアを持っていますか?

22
Firegun

それが言うように、それは呼び出し元のプロセスグループのすべてのメンバーに信号を送信します。

プロセスグループは、シェルでジョブ制御を実装するために使用されます(それらは他のものに使用できますが、対話型のシェルジョブ制御がそれらの存在の主な理由です)。

入力すると、 Ctrl-C、それらを開始したプロセスだけでなく、現在のジョブのすべてのプロセスが強制終了されます。また、それはバックグラウンドジョブを殺しません。

これは、プロセスグループによって実現されます。ジョブとは、シェルによって開始されたプロセスのグループであり、シェルはバックグラウンドまたはフォアグラウンド(ターミナルのフォアグラウンドプロセスグループとして設定されているかどうかにかかわらず)に入れ、全体としてkillできます。

プロセスグループIDとセッションIDについては、ps -jj for Jobコントロール)。

PGID $xのプロセスグループを強制終了するには、次のようにします。

kill -- "-$x"

kill 0は、呼び出し元のプロセスグループを強制終了します。

/bin/kill 0を実行すると、シェルはkillコマンドを実行する新しいジョブを開始するため、killはそれ自体を強制終了するだけであることに注意してください。

killは通常シェル組み込みですが、killはシェルのプロセスグループを強制終了します。

ただし、シェルが対話型の場合、それはプロセスグループを管理するプロセスであるため、通常、シェルのプロセスグループには他のプロセスはありません。シェルによって開始されたすべてのプロセスは、他のプロセスグループにあります。

$ sleep 1000 &
[1] 22746
$ ps -j
  PID  PGID   SID TTY          TIME CMD
22735 22735 22735 pts/23   00:00:00 zsh
22746 22746 22735 pts/23   00:00:00 sleep
22749 22749 22735 pts/23   00:00:00 ps

上記では、sleeppsは2つの異なるプロセスグループにあり、1つはバックグラウンド、もう1つはフォアグラウンドにあり、シェルのプロセスグループとは異なります。

あなたはそうすることができます:

(man kill & sleep 1; ps -j; kill 0)

対話型シェルはそのサブシェルの新しいプロセスグループを開始し、サブシェルとman(およびポケットベル、groff ...のようにmanが開始した他のコマンド)は同じプロセスグループにあるため、kill 0そこで働くでしょう。 (上のsleepは、ページャーが開始するのに十分な時間を与えるためです。これにより、ページャーを強制終了する前にps -j出力で確認できます)。

27