221

I launched my program in the foreground (a daemon program), and then I killed it with kill -9, but I get a zombie remaining and I m not able to kill it with kill -9. How to kill a zombie process?

If the zombie is a dead process (already killed), how I remove it from the output of ps aux?

root@OpenWrt:~# anyprogramd &
root@OpenWrt:~# ps aux | grep anyprogram
 1163 root      2552 S    anyprogramd
 1167 root      2552 S    anyprogramd
 1169 root      2552 S    anyprogramd
 1170 root      2552 S    anyprogramd
10101 root       944 S    grep anyprogram
root@OpenWrt:~# pidof anyprogramd
1170 1169 1167 1163
root@OpenWrt:~# kill -9 1170 1169 1167 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]
root@OpenWrt:~# kill -9 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]
MOHAMED
  • 41,599
  • 58
  • 163
  • 268

9 Answers9

300

A zombie is already dead, so you cannot kill it. To clean up a zombie, it must be waited on by its parent, so killing the parent should work to eliminate the zombie. (After the parent dies, the zombie will be inherited by pid 1, which will wait on it and clear its entry in the process table.) If your daemon is spawning children that become zombies, you have a bug. Your daemon should notice when its children die and wait on them to determine their exit status.

An example of how you might send a signal to every process that is the parent of a zombie (note that this is extremely crude and might kill processes that you do not intend. I do not recommend using this sort of sledge hammer):

# Don't do this.  Incredibly risky sledge hammer!
kill $(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}')
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 1
    If the zombie is a dead process (already killed), how I remove it from the output of `ps aux`? – MOHAMED Jun 05 '13 at 16:19
  • 231
    The zombie must be waited on by its parent. Find its parent and figure out why that parent is not paying attention to its children, then file a complaint with social services. ;) – William Pursell Jun 05 '13 at 16:22
  • 1
    I think using SIGTERM (the default for "kill") would be more appropriate, to give the processes about to be killed an opportunity to clean up before exiting. – jmng Nov 23 '15 at 14:26
  • 1
    Assuming you have process producing a lot of zombies it makes sense to 'uniq' the ids: `kill $(ps -A -ostat,ppid | awk '/[zZ]/{print $2}' | sort -u)` – ankon Sep 26 '17 at 16:30
  • 4
    usually, you can find the parent in the `PPid` row if you `cat /proc//status` – Daniel Andrei Mincă Sep 04 '18 at 11:22
72

You can clean up a zombie process by killing its parent process with the following command:

kill -HUP $(ps -A -ostat,ppid | awk '{/[zZ]/{ print $2 }')
marco
  • 4,455
  • 1
  • 23
  • 20
krishna murti
  • 1,061
  • 8
  • 9
  • This worked for me. It's basically the same as Mohammad Rafiee's solution, but presented in one simple line. – RichM Apr 10 '14 at 13:45
  • 7
    This command clears the zombie from the process table, but it does not 'kill' the zombie. The zombie is already dead. – William Pursell Jul 24 '14 at 12:45
  • 10
    The `grep` is not necessary. `ps ... | awk '/[zZ]/{print $2}'` – William Pursell Jul 24 '14 at 12:48
  • 2
    AFAICS, this command doesn't kill the zombie, but sends SIGHUP to its parent process (presumably killing the parent if it doesn't handle SIGHUP and causing the zombie to be reparented to init, as described in the previous answer). So be careful with this command, it might kill something you weren't expecting to... – Matthijs Kooijman Sep 08 '14 at 13:42
  • 1
    This didn't work for me . i did "kill -HUP processID" and the process is still there as a zombie – kommradHomer Nov 10 '14 at 08:11
  • @MatthijsKooijman, sure thing, it tried to kill my GUI but the process is still there. Blessed be tmux and detaching from the gnome terminal, a lesson for me not to run arbitrary commands before knowing what they do. – Bruno Kim Nov 05 '15 at 11:58
  • I think using SIGTERM (the default for "kill") would be more appropriate, to give the processes about to be killed an opportunity to clean up before exiting. – jmng Nov 23 '15 at 14:26
  • 1
    @WilliamPursell when you answer a question, please describe the consequence of using the command line and what it does explicitly because it does kill all the programs running on the computer. – Dalek Aug 31 '16 at 15:02
  • Works but there is an extra `{` in the original post. I rewrote it and added a sort and uniq in case there are dups `kill -HUP $(ps -A -ostat,ppid | awk '/[zZ]/{ print $2 }' | sort | uniq)` – Francesco Sep 14 '22 at 12:47
  • The command is incorrect, you have one extra `{` at the `awk` part. This is why:`kill -HUP $(ps -A -ostat,ppid | awk '{/[zZ]/ {print $2}')` output: `awk: cmd. line:1: {/[zZ]/ {print $2}`. This is the correct command: `kill -HUP $(ps -A -ostat,ppid | awk '/[zZ]/ { print $2 }')` – techsk8 Sep 24 '22 at 15:49
  • ```kill -9 $(ps -A -ostat,ppid | awk '/[zZ]/ { print $2 }') ``` in Ubuntu work fine. – burtsevyg Jun 23 '23 at 16:40
48

I tried:

ps aux | grep -w Z   # returns the zombies pid
ps o ppid {returned pid from previous command}   # returns the parent
kill -1 {the parent id from previous command}

this will work :)

PythoNic
  • 303
  • 5
  • 13
Mohammad Rafiee
  • 701
  • 5
  • 10
34

Found it at http://www.linuxquestions.org/questions/suse-novell-60/howto-kill-defunct-processes-574612/

2) Here a great tip from another user (Thxs Bill Dandreta): Sometimes

kill -9 <pid>

will not kill a process. Run

ps -xal

the 4th field is the parent process, kill all of a zombie's parents and the zombie dies!

Example

4 0 18581 31706 17 0 2664 1236 wait S ? 0:00 sh -c /usr/bin/gcc -fomit-frame-pointer -O -mfpmat
4 0 18582 18581 17 0 2064 828 wait S ? 0:00 /usr/i686-pc-linux-gnu/gcc-bin/3.3.6/gcc -fomit-fr
4 0 18583 18582 21 0 6684 3100 - R ? 0:00 /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/cc1 -quie

18581, 18582, 18583 are zombies -

kill -9 18581 18582 18583

has no effect.

kill -9 31706

removes the zombies.

smac89
  • 39,374
  • 15
  • 132
  • 179
Sergio
  • 341
  • 3
  • 2
  • 5
    well that just killed `init` for me, and now I can't do anything and am forced to restart... the zombie process is Java, taking 3.4GB out of 4GB of RAM – Tcll May 19 '15 at 21:43
29

I tried

kill -9 $(ps -A -ostat,ppid | grep -e '[zZ]'| awk '{ print $2 }')

and it works for me.

Pieter Goosen
  • 9,768
  • 5
  • 35
  • 55
Jeoffrey
  • 291
  • 3
  • 2
1

Sometimes the parent ppid cannot be killed, hence kill the zombie pid

kill -9 $(ps -A -ostat,pid | awk '/[zZ]/{ print $2 }')
Thiago Conrado
  • 726
  • 8
  • 15
1

Combining a few answers here into an elegant approach where you confirm which process is gone zombie before killing it. Add the script to .bashrc/.zshrc and run the killZombie command.

killZombie() {
    pid=$(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}');
    if [ "$pid" = "" ]; then
        echo "No zombie processes found.";
    else
        cmd=$(ps -p $pid -o cmd | sed '1d');
        echo "Found zombie process PID: $pid";
        echo "$cmd";
        echo "Kill it? Return to continue… (ctrl+c to cancel)";
        read -r;
        sudo kill -9 $pid;
    fi
}
Cwista
  • 361
  • 1
  • 11
0

On mac non of the above commands/instructions worked. To remove zombie processes you can right click on docker-icon->troubleshot->clean/purge Data.

enter image description here

Yasin Yaqoobi
  • 1,888
  • 3
  • 27
  • 38
0

I do not dare to try above methods.

My solution is htop then detect which process have multiprocessing.spawn and kill -9 it.

  • If you dare read others answer, you would see that the accepted answer explain and give the exact kill command to run (with only one step) – Elikill58 Nov 04 '21 at 10:50