2

I have a script spawning two zombies. I can kill the group via kill -- -<parent-pid>, but when invoked by the PHP interpreter, that won’t work although killing every single process manually will.

The script is

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

and the PHP file just invokes it:

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

From the shell directly:

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

... and 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

only killing the PHP parent process will work:

$ 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

Any ideas on that?

  • Could you run the commands with LC_ALL=C (so, for example, LC_ALL=C kill 19939 19938 19937 so we can see the messages in English? I translated the ones I was sure about, but both "Fertig" and "Beendet" seem to mean something like "done" so I couldn't guess what message each was supposed to be. – terdon Mar 17 '17 at 9:09
  • I'm not sure what kill -- pid does, but I think you might want to replace that with kill -1 pid which sends the HUP/HangUP signal to the process. – Michael D. Mar 17 '17 at 9:12
  • The minus before the pid means "kill group" and the double dash prevents kill to interpret that as an option. I do not intend to send "signal 1" as your command would do. – karlsebal Mar 17 '17 at 9:17
  • Actually, kill with no signal specified sends signal 1 (TERM), so there's no difference between kill -1 -PID and kill -- -PID. But yes, when a PID is < 1 that does mean "kill group" and that's precisely why it didn't work in your case, as I explain in my answer. – terdon Mar 17 '17 at 9:34
2

The kill command, when given a PID that is < -1, treats it as a process group ID (PGID), not as a process ID. This is documented in info kill:

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

If we take your example again:

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

The PGID is the PID of the topmost parent process of the process tree, in this case 19935. However, you tried to kill the processes belonging to the process group with ID 19937 and 19936, Neither of which are actually process group IDs. The PGID is 19935.

You can perhaps see this more clearly with ps. If I run the same commands on my system:

$ 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

In the example above, the PGID of the group is 12882, so that's what I need to use if I want to kill everything in the group.

When you run the command from the shell directly, the topmost parent process is the PID of the shell script, so you can kill all processes in its tree by running 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

But that's because the PID of the shell script is the PGID of the group.

  • Perfect, thank you very much! I was not aware that ”process group“ is an own concept. I imagined more like a tree where I can ”cut branches“ – karlsebal Mar 17 '17 at 9:42
  • @khaoz ah, no, not quite. You can see the POSIX definition here – terdon Mar 17 '17 at 9:46
  • That was very instructive, thank you very much! – karlsebal Mar 17 '17 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.