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

sleep 1d&
sleep 1d

and the PHP file just invokes it:


From the shell directly:

$ ./spawn&
[1] 19871    
$ pstree -p 19871
$ kill -- -19871    
$ pstree -p 19871
[1]+  Terminated                 ./spawn

... and via PHP:

$ php -f zomby.php &
[1] 19935    
$ pstree -p 19935
$ 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
$ 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, 2017 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, 2017 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, 2017 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, 2017 at 9:34

1 Answer 1


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

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'
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'
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, 2017 at 9:42
  • @khaoz ah, no, not quite. You can see the POSIX definition here
    – terdon
    Mar 17, 2017 at 9:46
  • That was very instructive, thank you very much!
    – karlsebal
    Mar 17, 2017 at 10:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .