Hello, all professionals,
I used subprocess.Popen to launch a process, right now I am planning to shut it down after a given time. Can I use subprocess.kill() to fulfill that? (I do not know how to do that cuz every time I will receive a error message.)

import subprocess
import time
pid = subprocess.Popen(args = ["gonome-terminal", ""--command = xxxx"]).pid
''' this will launch a process as I specified in the second argument'''
time.sleep(5.0)
subprocess.kill(pid)
'''Try to kill the process.'''

(However, I do not figure out how to fulfill this. Every time, there is an error says: 'unbound method kill() must be called with Popen instance as first argument (got int instance instead)'

Thank you for your considerations.
I appreciate all you helps
Bo:$;)

Recommended Answers

All 14 Replies

I use os.kill(), but some of these are OS dependent and Python version dependent. Take a look at Doug Hellmann's examples for starters.

I use os.kill(), but some of these are OS dependent and Python version dependent. Take a look at Doug Hellmann's examples for starters.

Thanks.

Sorry, I still have not found the way to implement my thought..
Could you give me more clues?
I appreciate your help.

To be more specific, I changed my original code as follows

import os, signal, subprocess, time
proc1 = subprocess.Popen(args=["gnome-terminal", "--command=kvm -hda /path/xp.img "]).pid
time.sleep(2.0)
os.kill(proc1, signal.SIGTERM)

Still, proc1 is not killed..
I need your help. Many thanks!

I works fine on my Slackware system. Try it with just "gnome-terminal". You may have to pass "shell=True" depending. Also, are there any error messages as it should kill the subprocess or report some kind of error. Finally, try it split into two lines, although that shouldn't matter

proc1 = subprocess.Popen(args=["gnome-terminal"], shell=True)
os.kill(proc1.pid, signal.SIGTERM)

I works fine on my Slackware system. Try it with just "gnome-terminal". You may have to pass "shell=True" depending. Also, are there any error messages as it should kill the subprocess or report some kind of error. Finally, try it split into two lines, although that shouldn't matter

proc1 = subprocess.Popen(args=["gnome-terminal"], shell=True)
os.kill(proc1.pid, signal.SIGTERM)

Hi, Woooee,
This probably works before I add a line "time.sleep(1)". However, after I supplement this order, child process cannot be killed.
Wish you can help me.
I appreciate your previous comments.

Dear all experts,
I tried several options on this issue, such as:

import subprocess, os, signal, time
proc1 = subprocess.Popen("gnome-terminal", shell=True)
print proc1.pid
time.sleep(1.0)
proc1.kill() # or os.kill(proc1.pid, signal.SIGKILL)

The method I used can not kill the child process "proc1". While, if I erase the time.sleep(1.0), it seems like the child process could be killed. But this is not practical though.
In the end, I appreciate all you aids.

Dear all experts,
I tried several options on this issue, such as:

import subprocess, os, signal, time
proc1 = subprocess.Popen("gnome-terminal", shell=True)
print proc1.pid
time.sleep(1.0)
proc1.kill() # or os.kill(proc1.pid, signal.SIGKILL)

The method I used can not kill the child process "proc1". While, if I erase the time.sleep(1.0), it seems like the child process could be killed. But this is not practical though.
In the end, I appreciate all you aids.

The problem is that gnome-terminal starts another (bash) process. For example if I start a gnome-terminal with pid 17873, I also have a bash process with pid 17875. To kill the terminal, one must kill the bash process.
The only way I see to get the bash process' pid is to examine the content of the /proc directory after the gnome-terminal has been launched.
Something like

>>> term = sp.Popen(["gnome-terminal"])
>>> term.wait()
0
>>> print term.pid
18901
>>> # now look in /proc to find the child process (with a pid close to 18901)

This function may help

def children_pid(pid):
    """get the list of the children pids of a pid (linux only)"""
    import subprocess as SP
    proc = SP.Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True, stdout=SP.PIPE)
    pidppid  = [x.split() for x in proc.communicate()[0].split("\n") if x]
    return list(int(p) for p, pp in pidppid if int(pp) == pid)

This function may help

def children_pid(pid):
    """get the list of the children pids of a pid (linux only)"""
    import subprocess as SP
    proc = SP.Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True, stdout=SP.PIPE)
    pidppid  = [x.split() for x in proc.communicate()[0].split("\n") if x]
    return list(int(p) for p, pp in pidppid if int(pp) == pid)

Thank you Gribouillis,
Let me try that, and give you responses.
Again, I am grateful for your help.

This function may help

def children_pid(pid):
    """get the list of the children pids of a pid (linux only)"""
    import subprocess as SP
    proc = SP.Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True, stdout=SP.PIPE)
    pidppid  = [x.split() for x in proc.communicate()[0].split("\n") if x]
    return list(int(p) for p, pp in pidppid if int(pp) == pid)

First of all, thank you Gribouillis.
I combine your advice together. The code looks like this:

import subprocess as SP

def children_pid(pid):
    """get the list of the children pids of a pid (linux only)"""    
    proc = SP.Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True, stdout=SP.PIPE)
    pidppid  = [x.split() for x in proc.communicate()[0].split("\n") if x]
    return list(int(p) for p, pp in pidppid if int(pp) == pid)
    
term = SP.Popen(["gnome-terminal"])
term.wait()
print term.pid
term.wait()
print children_pid(term.pid)

However, function "children_pid(term.pid)" does not have output except a "[]".
The eventual output is:
2416
[]

Again, I am grateful for your consideration.
Regards.
I am still confused about this problem..

First of all, thank you Gribouillis.
I combine your advice together. The code looks like this:

import subprocess as SP

def children_pid(pid):
    """get the list of the children pids of a pid (linux only)"""    
    proc = SP.Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True, stdout=SP.PIPE)
    pidppid  = [x.split() for x in proc.communicate()[0].split("\n") if x]
    return list(int(p) for p, pp in pidppid if int(pp) == pid)
    
term = SP.Popen(["gnome-terminal"])
term.wait()
print term.pid
term.wait()
print children_pid(term.pid)

However, function "children_pid(term.pid)" does not have output except a "[]".
The eventual output is:
2416
[]

Again, I am grateful for your consideration.
Regards.
I am still confused about this problem..

I obtained children pids by running gnome-terminal with the option --disable-factory. I cant help you much because in my mandriva system, the gnome-terminal is destroyed without problem.

I obtained children pids by running gnome-terminal with the option --disable-factory. I cant help you much because in my mandriva system, the gnome-terminal is destroyed without problem.

Never mind, thank you all the same.
I am wondering if I can send "ctrl-c" to close the terminal mandatorily?
By the way, do you know how to fulfill this?
I appreciate your continuous help.

First of all, thank all the experts for their precious comments.
Problem has been solved. Here is the eventual code:

import subprocess, time
proc1 = subprocess.Popen(args=['gnome-terminal','--command=XXX'])
print 'proc1\'s pid = ',proc1.pid
time.sleep(5)
proc1.terminate()

Anyway, I tried Popen.terminate() before, but it works just then. I do not know the exact reason but this is a very common trial-and-error.
Again, I am grateful for all the contributions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.