views:

7248

answers:

9

I basically want to kill a whole process tree. What is the best way to do this using any common scripting languages. I am looking for a simple solution.

+1  A: 

Since you say you can use any common scripting languages, you could take a look at this question: How can I kill a whole process tree with Perl?

Adam Bellaire
I didn't find any of their answers conclusive. I checked the CPAN module and it didn't seem to do what was described and I can't use the 'kill' command with a GPID.
Adam Peck
Oh I see. I would retract my answer, except that it might be a useful explanation in case someone else comes along and thinks your question is a dupe.
Adam Bellaire
A: 

With a morning-after-process.

you mean "the next day pill"?
vmarquez
+4  A: 

if you know pass the pid of the parent process, here's a shell script that should work:

for child in $(ps -o pid,ppid -ax | \
   awk "{ if ( \$2 == $pid ) { print \$1 }}")
do
  echo "Killing child process $child because ppid = $pid"
  kill $child
done
brad.lane
+4  A: 

brad's answer is what I'd recomment too, except that you can do away with awk altogether if you use the --ppid option to ps.

for child in $(ps -o pid -ax --ppid $PPID) do ....... done

Kim
This doesn't work for me unless I take out the -ax, for some reason (Centos5). Otherwise this is great!
xitrium
+13  A: 

You don't say if the tree you want to kill is a single process group. (This is often the case if the tree is the result of forking from a server start or a shell command line.) You can discover process groups using GNU ps as follows:

 ps x -o  "%p %r %y %x %c "

If it is a process group you want to kill, just use the kill(1) command but instead of giving it a process number, give it the negation of the group number. For example to kill every process in group 5112, use kill -TERM -5112.

Norman Ramsey
kill -74313-bash: kill: 74313: invalid signal specificationIf i add the kill -15 -GPID it worked perfectly.
Adam Peck
As usual with almost any command, if you want a normal argument that starts with a - to not be interpreted as a switch, precede it with --: kill -- -GPID
ysth
A: 

Thanks for your wisdom, folks. My script was leaving some child processes on exit and the negation tip made things easier. I wrote this function to be used in other scripts if necessary:

# kill my group's subprocesses:          killGroup
# kill also myself:                      killGroup -x
# kill another group's subprocesses:     killGroup N  
# kill that group all:                   killGroup -x N
# N: PID of the main process (= process group ID).

function killGroup () {
    local prid mainpid
    case $1 in
        -x) [ -n "$2" ] && kill -9 -$2 || kill -9 -$$ ;;
        "") mainpid=$$ ;;
         *) mainpid=$1 ;;
    esac
    prid=$(ps ax -o pid,pgid | grep $mainpid)
    prid=${prid//$mainpid/}
    kill -9 $prid 2>/dev/null
    return
}

Cheers.

A: 

ps -o pid= --ppid $PPID | xargs kill -9

A: 

To kill a process tree recursively, use killtree.sh:

#!/bin/bash

killtree() {
    local _pid=$1
    local _sig=${2-TERM}
    for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
        killtree ${_child} ${_sig}
    done
    kill -${_sig} ${_pid}
}

if [ $# -eq 0 -o $# -gt 2 ]; then
    echo "Usage: $(basename $0) <pid> [signal]"
    exit 1
fi

killtree $@
zhigang
A: 

if you have pstree and perl on your system, you can try this:

perl -e 'kill 9, (`pstree -p PID` =~ m/\((\d+)\)/sg)'
lyman