Não é possível matar o grupo de processos quando invocado pelo PHP

2

Eu tenho um script que gera dois zumbis. Eu posso matar o grupo através de kill -- -<parent-pid> , mas quando invocado pelo interpretador PHP, isso não vai funcionar, embora matar todos os processos manualmente irá fazê-lo.

O script é

#!/bin/bash
sleep 1d&
sleep 1d

e o arquivo PHP apenas invoca:

<?php
exec("./spawn")
?>

Do shell diretamente:

$ ./spawn&
[1] 19871    
$ pstree -p 19871
spawn(19871)─┬─sleep(19872)
             └─sleep(19873)    
$ kill -- -19871    
$ pstree -p 19871
[1]+  Terminated                 ./spawn

... e via 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

apenas a morte do processo pai do PHP funcionará:

$ 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

Alguma ideia sobre isso?

    
por karlsebal 17.03.2017 / 09:56

1 resposta

2

O comando kill , quando recebe um PID que é < -1, trata-o como um ID de grupo de processos (PGID), não como um ID de processo. Isso está documentado em info kill :

 ‘PID < -1’
      The process group whose identifier is −PID.

Se pegarmos seu exemplo novamente:

$ pstree -p 19935
php(19935)───sh(19936)───spawn(19937)─┬─sleep(19938)
                                      └─sleep(19939)

O PGID é o PID do processo pai mais alto da árvore de processos, neste caso 19935 . No entanto, você tentou eliminar os processos pertencentes ao grupo de processos com ID 19937 e 19936 , sendo que nenhum deles é realmente IDs de grupos de processos. O PGID é 19935 .

Você talvez possa ver isso mais claramente com ps . Se eu executar os mesmos comandos no meu sistema:

$ 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

No exemplo acima, o PGID do grupo é 12882 , e é isso que preciso usar se quiser matar tudo no grupo.

Quando você executa o comando diretamente do shell, o processo pai mais importante é o PID do script de shell, portanto, você pode eliminar todos os processos em sua árvore executando 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

Mas isso acontece porque o PID do script de shell é o PGID do grupo.

    
por 17.03.2017 / 10:31