What does kill 0 do actually?

14,757

Solution 1

I couldn't find a note how kill 0 behaves in my kill man page (debian).

But I have two comments:

(1) "Process Group" might not be what you expect. You can display the Process Group ID (PGID) with ps -o "%p %P %r %c %a":

$ ps -o "%p %P %r %c %a"
  PID  PPID  PGID COMMAND         COMMAND
12124 12123 12124 zsh             -zsh
12212 12124 12212 man             man kill
12226 12212 12212 less            less
12302 12124 12302 ps              ps -o %p %P %r %c %a

So, the man together with the displaying pager tool (less) is in the same process group, but that is different from that of the shell (zsh in my case).

(2) There are probably two different kill commands. One built into bash (see bash(1), Section "SHELL BUILTIN COMMANDS") and the external /bin/kill. These two may behave differently! You can explicitly state which one you want to run by typing builtin kill or command kill instead of kill. The external command you can also run by specifying the path: /bin/kill.

Solution 2

To stop all of your processes and log yourself off, enter:

kill -kill 0

This sends signal 9, the SIGKILL signal, to all processes having a process group ID equal to the senders process group ID. Because the shell cannot ignore the SIGKILL signal, this also stops the login shell and logs you off

This is IBM's AIX Manual, but perhaps the concept applies.

This functionality does not exist in Linux "kill" (as I can see); but this is how it's "kill" behaves:

Killing 0 isn't killing the pid 0. Instead it is an option in kill to kill all processes in the current group. With your command you are killing everything in the process group ID (GID) of the shell that issued the kill command.

Solution 3

In your case you have two processes involved:

  1. Your shell.
  2. The man process that you put into background.

How exactly the kill command works depends on your shell, but, in most cases, it is a shell builtin, which, basically, simply invokes the kill(2) syscall. As you read in the man page, 0 is a special value that means “send the signal to all processes in the current process group”. So, when you type kill 0 you send SIGTERM (which is the default signal) to all processes in the current process group.

Now, the real question here is: what is the current process group? Long story short, process groups are used by shells to control shell pipelines (things like /bin/echo hello | /usr/bin/wc -c). When your shell runs a new command, it will create a new process group for the processes that a part of this command (e.g. in my example above it will create a proces group with two processes: echo and wc).

So, in your example, the shell will create a new process group for the man process that it starts (and all its children), you can see it by running:

$ ps -o pid,ppid,pgid,comm

(PPID is the parent PID, PGID is the process group).

And then you type kill 0 in your shell, which is in a process group of its own (remember, it created a new process group for man). So all that happens is SIGTERM is delivered to all processes in your shell’s process group, which is only the shell itself (and it ignores the SIGTERM).

Share:
14,757

Related videos on Youtube

Sniper
Author by

Sniper

Just another stackoverflow user cs.cmu.edu/~hanfeis

Updated on September 18, 2022

Comments

  • Sniper
    Sniper over 1 year

    In the man page, it says:

              0      All processes in the current process group are signaled
    

    And I tried like this:

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

    As I understood, kill 0 will kill all processes in the current process, which includes pid15247. However, it didn't do anything in this example. Does anyone have ideas about how to use it?

    • FatalError
      FatalError about 11 years
      What shell are you using?
    • Sniper
      Sniper about 11 years
      @FatalError I'm using Bash
    • Adam Katz
      Adam Katz over 7 years
  • chepner
    chepner about 11 years
    PPID is the parent process ID, which is often, but not necessarily, the process group ID. The correct column is PGID, which does not appear in the default ps output; you need to use the -o option to construct a custom format that includes it.
  • mpy
    mpy about 11 years
    @chepner: You are absolutely right, thanks! I was confused by my Cygwin's ps(1) man page, which states: "-l, --long: show process uids, ppids, pgids, winpids". Shame on me, I edited my answer accordingly. However, my statement (only man+pager have the same PGID) is correct now, as intended. (Before even that sentence was wrong :-()