2つのゾンビを生成するスクリプトがあります。グループを終了してこれを行うことはできますがkill -- -<parent-pid>
、各プロセスを手動で終了してもPHPインタプリタから呼び出すと機能しません。
スクリプトは
#!/bin/bash
sleep 1d&
sleep 1d
PHPファイルは次のように呼び出します。
<?php
exec("./spawn")
?>
シェルから直接:
$ ./spawn&
[1] 19871
$ pstree -p 19871
spawn(19871)─┬─sleep(19872)
└─sleep(19873)
$ kill -- -19871
$ pstree -p 19871
[1]+ Terminated ./spawn
...そしてPHPを通して:
$ php -f zomby.php &
[1] 19935
$ pstree -p 19935
php(19935)───sh(19936)───spawn(19937)─┬─sleep(19938)
└─sleep(19939)
$ kill -- -19937
bash: kill: (-19937) - No matching process found
$ kill -- -19936
bash: kill: (-19936) - No matching process found
$ kill 19939 19938 19937
$ Terminated
[1]+ Fertig php -f zomby.php
PHPの親プロセスだけを終了すると機能します。
$ php -f zomby.php &
[1] 20021
$ pstree -p 20021
php(20021)───sh(20022)───spawn(20023)─┬─sleep(20024)
└─sleep(20025)
$ kill -- -20021
$ pstree -p 20021
[1]+ Terminated php -f zomby.php
これについて考えていますか?
答え1
kill
指定されたPIDが-1未満の場合、コマンドはプロセスIDではなくプロセスグループID(PGID)として処理します。これに関する文書は次のとおりですinfo kill
。
‘PID < -1’
The process group whose identifier is −PID.
あなたの例をもう一度見てみると、次のようになります。
$ pstree -p 19935
php(19935)───sh(19936)───spawn(19937)─┬─sleep(19938)
└─sleep(19939)
PGIDは、プロセスツリーの上部にある親プロセスのPIDです(この場合)19935
。ただし、実際には19937
、19936
プロセスグループIDではなく、IDおよびプロセスグループに属するプロセスを終了しようとしています。 PGIDはい19935
。
これにより、より明確に確認できますps
。私のシステムで同じコマンドを実行する場合:
$ php -f ./zombie.php &
[2] 12882
$ ps -o pid,ppid,pgid,command | grep -E '[P]GID|[1]2882'
PID PPID PGID COMMAND
12882 1133 12882 php -f ./zombie.php
12883 12882 12882 /bin/bash ./spawn
12884 12883 12882 sleep 1d
12885 12883 12882 sleep 1d
上記の例では、グループのPGIDはその12882
ため、そのグループのすべてのエントリを終了するにはそれを使用する必要があります。
シェルから直接コマンドを実行している場合、最上位の親プロセスはシェルスクリプトのPIDであるため、次を実行してそのツリー内のすべてのプロセスを終了できますkill -- -PID
。
$ ./spawn &
[3] 14213
terdon@tpad foo $ ps -o pid,ppid,pgid,command | grep -E '[P]GID|[1]4213'
PID PPID PGID COMMAND
14213 1133 14213 /bin/bash ./spawn
14214 14213 14213 sleep 1d
14215 14213 14213 sleep 1d
しかし、これはシェルスクリプトのPIDがグループのPGIDであるためです。