How to find zombie process?
Solution 1
To kill a zombie (process) you have to kill its parent process (just like real zombies!), but the question was how to find it.
Find the zombie (The question answered this part):
a@SERVER:~$ ps aux | grep 'Z'
What you get is Zombies and anything else with a Z in it, so you will also get the grep:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
usera 13572 0.0 0.0 7628 992 pts/2 S+ 19:40 0:00 grep --color=auto Z
usera 93572 0.0 0.0 0 0 ?? Z 19:40 0:00 something
Find the zombie's parent:
a@SERVER:~$ pstree -p -s 93572
Will give you:
init(1)---cnid_metad(1311)---cnid_dbd(5145)
In this case you do not want to kill that parent process and you should be quite happy with one zombie, but killing the immediate parent process 5145 should get rid of it.
Additional resources on askubuntu:
Solution 2
Even though this question is old I thought everyone deserved a more reliable answer:
ps axo pid=,stat=
This will emit two whitespace-delimited columns, the first of which is a PID and the second of which is its state.
I don't think even GNU ps
provides a way to filter by state directly, but you can reliably do this with awk
ps axo pid=,stat= | awk '$2~/^Z/ { print }'
You now have a list of PIDs which are zombies. Since you know the state it's no longer necessary to display it, so that can be filtered out.
ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'
Giving a newline-delimited list of zombie PIDs.
You can now operate on this list with a simple shell loop
for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do
echo "$pid" # do something interesting here
done
ps
is a powerful tool and you don't need to do anything complicated to get process information out of it.
(Meaning of different process states here - https://unix.stackexchange.com/a/18477/121634)
Solution 3
Less is more though:
ps afuwwx | less +u -p'^(\S+\s+){7}Z.*'
That's like, give me a forest (tree) of all users' processes in a user oriented format with unlimited width on any tty and show it to me at half a screen above where it matches the case that the 8th column contains a Z, and why not highlight the whole line.
User oriented format seems to mean:
USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND
so the Zombie status will show up in the 8th column.
You can throw in an N
before the p
if you want line numbers, and a J
if you want an asterisk at the match. Sadly if you use G
to not highlight the line that asterisk will not show, though J
creates space for it.
You end up getting something that looks like:
…
root 2919 0.0 0.0 61432 5852 ? Ss Jan24 0:00 /usr/sbin/sshd -D
root 12984 0.0 0.1 154796 15708 ? Ss 20:20 0:00 \_ sshd: lamblin [priv]
lamblin 13084 0.0 0.0 154796 9764 ? S 20:20 0:00 \_ sshd: lamblin@pts/0
* lamblin 13086 0.0 0.0 13080 5056 pts/0 Z 20:20 0:00 \_ -bash <defunct>
lamblin 13085 0.0 0.0 13080 5056 pts/0 Ss 20:20 0:00 \_ -bash
root 13159 0.0 0.0 111740 6276 pts/0 S 20:20 0:00 \_ su - nilbmal
nilbmal 13161 0.2 0.0 13156 5004 pts/0 S 20:20 0:00 \_ -su
nilbmal 13271 0.0 0.0 28152 3332 pts/0 R+ 20:20 0:00 \_ ps afuwwx
nilbmal 13275 0.0 0.0 8404 848 pts/0 S+ 20:20 0:00 \_ less +u -Jp^(\S+\s+){7}Z.*
…
You could follow this up with (and it'll detect if your terminal likes -U Unicode or -A Ascii):
pstree -psS <PID LIST>
OR just, you know, use the up-arrow in less
to follow that tree/forest through the hierarchy; which is what I was recommending with the "Less is more" approach.
Solution 4
ps aux | awk '{ print $8 " " $2 }' | grep -w Z
From: http://www.cyberciti.biz/tips/killing-zombie-process.html
From the comments an improved one:
for p in $(ps jauxww | grep Z | grep -v PID | awk '{print $3}'); do
for every in $(ps auxw | grep $p | grep cron | awk '{print $2}'); do
kill -9 $every;
done;
done;
Careful though: this one also kills the proces.
Solution 5
I usually find them on my server with
ps aux | grep 'defunct'
Related videos on Youtube
Pablo
Updated on September 18, 2022Comments
-
Pablo over 1 year
System information as of Fri Mar 9 19:40:01 KST 2012 System load: 0.59 Processes: 167 Usage of /home: 23.0% of 11.00GB Users logged in: 1 Swap usage: 0% IP address for eth1: 192.168.0.1 => There is 1 zombie process. Graph this data and manage this system at https://landscape.canonical.com/ 10 packages can be updated. 4 updates are security updates. Last login: Fri Mar 9 10:23:48 2012 a@SERVER:~$ ps auxwww | grep 'Z' USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND usera 13572 0.0 0.0 7628 992 pts/2 S+ 19:40 0:00 grep --color=auto Z a@SERVER:~$
How to find that zombie process?
-
dlin almost 12 yearswhy dont you open the system monitor and search for the zombie process?
-
clicky about 11 yearsHow to do that on a headless no-X server?
-
arielf almost 6 yearsSurprising that no answer below actually says that there's no zombie process in the system based on the above output. If there really was one, the
ps auxwww | grep 'Z'
command should have shown a process in aZ
state. The "system information" saying=> There is 1 zombie process.
seems to be a bug. Either that, or there's missing information in the question.
-
-
Pablo about 12 yearsstill returns nothing. I think my way also wasn't wrong.
-
FvD almost 11 yearsThe result you show in your answer is the the grep command itself, not the zombie process. It is the same mis-interpratation as Pablo made in his answer. The answer by Rinzwind below does actually look for the zombie process and list them. Another option could be to grep for "defunct"
-
Greg M. Krsak about 10 yearspstree -H your_desired_pid -p
-
Duncanmoo about 10 yearsThanks Greg for adding to the discussion, but please remember this is a help site, just pasting a command without explaining anything is not helpful to most people coming here looking for help.
-
0xC0000022L almost 10 years
awk
is also a powerful tool which doesn't just split text but can also match it. +1 ... the others usedgrep
where it's unnecessary and imprecise. -
Terrance over 8 yearsThis is a great answer! It is still valid today! I was able to find my zombie process and kill its parent process without any problems. Thank you!
-
chovy over 8 yearsso now that i have list of zombie processes. how do i kill them?
-
Sorpigal over 8 years@chovy: It will depend, but generally involves killing or signalling the parent. Other answers here go in to that. From within the loop shown above you can find the parent pid like this:
ps -p "$pid" -opid=,ppid=
-
chovy over 8 yearsif i will the parent won't it kill all its child processes? I just want to kill the one zombie process. I know the ppid.
-
Sorpigal over 8 years@chovy: The command you want is
kill -CHLD "$ppid"
but even this may not be enough, read this entire post to understand what your options are. -
JDS about 8 yearsif you do not have pstree installed,
ps wauxf
does the same thing -
ton over 6 yearsJust my 2 cents...
ps aux | grep 'Z' | grep -vE "(PID|grep)" | tr -s " " | cut -d " " -f2 | xargs -i pstree -p -s {}
-
dlamblin about 6 yearsI dunno;
grep
may just be clearer as there's only one reasonZ
would appear in the output ofps axo pid=,stat=
. Why notps axo pid=,stat=|grep Z
orps axo pid=,stat=|sort -k 2r|head -1
orps axo stat=,pid=|sort -r|head -1
? -
Sorpigal about 6 yearston: If a process name has Z in it you will get an incorrect match. If you want to run pstree on each pid you can do so by piping the output of the awk command above to xargs without resorting to two extra, needless filtering programs. @dlamblin: If you do not strip the STAT column from the output of ps it is harder to use the pid for anything other than human consumption. Why would you do either of these less-correct and more complicated things when I have already provided to you a solution which is better in every way? There are many things you can do but not many things you should do.
-
Sorpigal about 6 yearsResorting to stripping one column out of the
j
format for this is needlessly complicated. Use-o
to select what you want instead. -
Sorpigal about 6 yearsUsing
aux
and munging strings out of it is needlessly unreliable when you can use-o
and request exactly what you want. Useps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'
instead. -
arielf almost 6 years
ps j
doesn't print all processes in the system. It only lists the current user procs (in BSD jobs style) so it may miss zombie processes. -
pevik over 5 yearsYou can also try
ps aux |grep "defunct"
-
Ding-Yi Chen about 5 yearsI do suggest to add
ppid=
to the options list, so no need to use a separate command to obtain ppid. -
Sorpigal about 5 yearsThe 2nd example is hellishly unreliable and the former is needlessly verbose (try
ps axo pid=,stat= | awk '$2~/Z/ {print $1}'
instead). -
Sorpigal over 4 years@Ding-YiChen: Yes, that would be wise. In that case I would also change to a
while read
construct, e.g.: (bash only):while IFS=' ' read -r pid ppid ; do echo "zombie pid $pid parent $ppid" ; done < <(ps axo pid=,ppid,stat= | awk '$3~/^Z/ { print $1, $2 }')
-
Karl Pokus over 4 yearsI'd add the
-w
flag. As ingrep -w Z
to only match the word Z and avoid clutter. -
Ilya Zub over 3 yearsI like how the first command also selects the found process. Thank you!
-
dlamblin over 3 years@IlyaZub If only I could show how that looks without needing to use a screenshot.
-
Drakes over 2 years
ps aux | grep '<[d]efunct>'
to avoid including the grep