• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 590
  • Last Modified:

How do I kill a process and all its children?

I have a GUI which forks a shell command
which in turn causes a series of forks
to happen so that I end up with a chain
of processes.  In the GUI I want to add
a button to kill the forked processes and
wish to program this easily.  So far the
only solution I can think of is to build up
a tree by walking the PPID PID fields returned
by ps starting with the PID of the original
forked process which I have and looking for
all PIDs that have that PID as their PPID
and then repeating this process recursively
until there are no more children to be found.
Once the tree is build I would then kill all
the processes in the tree with kill -9 pid for
each item in the tree.  This is rather tedious to
write so I am hoping to find a Unix command that
lets me kill a process and all of its children
processes transitively.
1 Solution
If you do a kill -9 `ps -ef | grep "<pid>" | awk '{ print $2 }'`, this will do it.  You can add some extra error checking (like using awk to tell if $2 (the process) or $3 (the parent) are the pid).  Note that the first is a backtick (shift+~), and the inner is a single quote.
I hope this helps a little.
Correction, put spaces around the pid, and that will handle the $2 and $3 stuff I was talking about earlier:

kill -9 `ps -ef | grep " <pid> " | awk '{ print $2 }'`
Hi wkf,

   use the following command:

   kill -9 `ps -ef | grep NAME | awk '{print $2}' `

   where: NAME is a program name you want to kill or the usr login
   name if you want to kill all the processes for that user.

   su as "root" before type in the above command, if you want to kill
other user's process.
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

yuzh, That's a good idea, but it will give undesirable results if you have more than one instance of that program running, though.  Of course, without knowing whether this is legal in wkf's environment, I can't say for sure that it's a problem.
If you have more than one instance of that program, and you only want  to kill one of them, all you need to do is:

    ps -ef | grep program | more

    find out which parent process ID and its child process you want to kill, then replace the NAME with the parent process ID, it'll kill all of them.
In Solaris with

Make man pkill
yuzh, you can't do the more if you're trying to automate the kill in a program.  It requires user intervention at that point.  And what about the instance where you have a program called prog, somebody's looking at the log (tail -f prog.log), and there's another process (say a watchdog process to ensure that the daemon stays alive) called prog_watchdog.ksh.  Granted, prog is a bad name for a program, but you could plug in any other name and I've seen systems designed this way.  That's all I was saying.
Well, if you want to kill the daemon, that is easy. in a script situation, you can find the deamon PID first, then exclusive this ID from the kill list.

   deamon PID=`ps -ef | grep mydeamon | grep -v greg | awk '{print $2}'`

   from your killing list, you do:

   kill -9 `ps -ef | grep myprog | grep -v deamon-PID | awk '{print $2}'`

Why would you exclude the daemon pid from your kill list if you want to kill the daemon?
what about "killall processname"? would it help? :)

Depending on how the children are forked, it is simply a matter of killing the parent nicely.

kill <PID>

Do not use '-9' as this will not give the parent a chance to kill its children and they will be adopted by init.

When the script is called capture the PID into a file.  Then let the kill button run this command:

kill `cat $PID_FILE`

where PID_FILE is an environment variable containing the PID.

This is all you need to do.

Regards, Nisus
Listen to Nisus above, DO NOT USE kill -9 unless the process will not die gracefully. Like he said, just kill the parent with a kill, this parent will kill the child processes before it dies.
I agree with "haho" above that 'killall' is a useful command, just don't use it on Solaris. It really kills ALL processes. It works fine on IRIX though, and will accept -9  (or -KILL) if it's nessecary.
Make your GUI program run the children in their own process group. See setpgrp(2). Provided that the children don't try to change process group themselves, you'll be able to kill them by giving a negative argument to kill, ie.

kill -TERM -process_group_number

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now