Trying to kill a process and all of its children & grandchildren. How?
Linux - GeneralThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Introduction to Linux - A Hands on Guide
This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.
Click Here to receive this Complete Guide absolutely free.
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).
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?
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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.