LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 10-30-2008, 07:27 PM   #1
BrianK
Senior Member
 
Registered: Mar 2002
Location: Los Angeles, CA
Distribution: Debian, Ubuntu
Posts: 1,334

Rep: Reputation: 51
Trying to kill a process and all of its children & grandchildren. How?


I have a python script that spawns a shell script with subprocess.Popen. Sometimes I want to stop (or even exit) the program with a cntl-c before the shell script is done. I believe I have to do a system call to kill those subprocesses. (This, of course, is inside a KeyboardInterrupt exception)

All the subprocesses are part of a process group. I could kill that group, but that would kill the python script as well (from itself, no less), which is not what I want to do. I want to kill the spawned process and all of it's children. I do know the pid of the spawned process, but I do not know the pid of its children (I could find them by doing another ps system call & parsing the results, but I'm hoping there's a better way).

if I run this command:
Code:
ps eo stat,pid,pgid,ppid,pcpu,comm
I can see the stuff in quesiton here:
Code:
STAT   PID  PGID  PPID %CPU COMMAND
Sl+   4551  4551 17369  0.0 python
S+    4935  4551  4551  0.0 zegrep
R+    5004  4551  4935  1.3 gzip
S+    5005  4551  4935  0.0 zegrep
S+    5009  4551  5005  0.0 zegrep
S+    5010  4551  5009  0.0 zegrep
S+    5011  4551  5010  3.2 grep
S+    5012  4551  5009  0.0 sed
So 4935 is the first subprocess that is spawned. All other subprocess are related to that one in some way.. either a child or a grandchild (or great grandchild, etc).

I don't want to just kill the group 4551 because that will kill myself (the python script). So, is there a nice, pythonic way to kill all those subprocesses without killing 4551?

Last edited by BrianK; 10-30-2008 at 07:29 PM.
 
Old 10-30-2008, 08:44 PM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 7.7 (?), Centos 8.1
Posts: 17,818

Rep: Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558Reputation: 2558
Well, I don't know Python, but I'd record the pids as I went (ie the top prog records the pids as they are spawned) and write a fn to kill them on demand.
Sounds like you want to install a sig handler for ctrl-c (SIGINT iirc) as well, to call the kills.
 
Old 10-30-2008, 09:39 PM   #3
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,186

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
Or have your ancestor Python script spawn a second script to do all the other spawning, and then kill that (single) ancestor of all the rest.
 
Old 10-30-2008, 10:45 PM   #4
BrianK
Senior Member
 
Registered: Mar 2002
Location: Los Angeles, CA
Distribution: Debian, Ubuntu
Posts: 1,334

Original Poster
Rep: Reputation: 51
Because the subprocess is a shell script, I don't know how to get pids of the things it spawns, nor do I know how to tell it to kill its kids.

My not-so-elegant solution:
Code:
    def killPGroup(self):
        """
        Attempts to find all childred & grandchildren of the spawned subproces
        and gets all Ted Bundy with them.
        """
        # get the pid, pgid, ppid of our current processes:
        command = "ps eo pid,pgid,ppid"
        psraw = os.popen(command).readlines()
        psList = []
        killList = []
        for ps in psraw[1:]: # 1: gets rid of header
            psList.append(map(int,ps.split()))
        pgid = 0

        # find the pgid of the spawned subprocess:
        for ps in psList:
            if int(self.p.pid) in ps:
                pgid = ps[1]
                break
        if pgid == 0:
            print >>sys.stderr, "Something screwed up trying to find pids. fudge."
            return

        # get a list of all pids in the pgid except the group owner:
        for ps in psList:
            if pgid in ps and pgid != ps[0]:  # check [0] so we don't kill ourselves
                killList.append(ps[0])

        # don't do anything if we didn't find anything:
        if len(killList) <= 0:
            return

        # kill the bastards:
        command = "kill %s" % string.join(map(str,killList[:-1]),' ')
        print "killing subprocesses with '%s'" % command
        os.system(command)
        print "done with kill"
I'm still very open to other solutions.


PTrenholme - I don't really follow you there.. well.. kinda, but it seems a little round-about, though maybe it is actually a more "proper" way of doing it that climbing the ps tree.


edited to add: hrm.. This probably should have been posted in the Programming forum. If someone feels like moving it, feel free.

Last edited by BrianK; 10-30-2008 at 10:56 PM.
 
Old 10-31-2008, 02:36 PM   #5
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,186

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
Well, it avoids the question of the PIDs of the children (since killing the parent will kill all it children - unless they've been disowned), and also lets you (the Python ancestor) have several different prolific children which can be killed, along with any children they have, with a single "kill" of a prolific child process.

It seems to me to be more elegant and flexible then walking the process tree collecting PIDs since the kernel can handle all that for you.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Shell Script : Kill a running process when another process starts ashmew2 Linux - General 3 08-20-2008 04:47 AM
kill process cad Linux - General 4 02-13-2007 02:40 PM
cannot kill process (kill -9 does not work) mazer13a Linux - General 1 05-27-2005 03:32 PM
Get bash to kill its children upon death Temjin Linux - General 2 05-27-2005 09:41 AM
can't kill the process ust Linux - Software 1 09-15-2004 07:05 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 03:29 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration