I am trying to kill a subprocess via its pid by using subprocess.call() to do it. I obtain the pid by assigning return to a value like this:
return = subprocess.Popen(["sudo", "scrolling-text-example", "-y7"])
x= return.pid
When when I am ready to end this subprocess I am using this code:
subprocess.call(["sudo","kill",str(x)])
This does not kill the subprocess, but if I open terminal (let's say x is 1234), and type: sudo kill 1234 , it will kill the subprocess.
Use x = str(return pid) and subprocess.call(["sudo","kill","-9",x]) and then try to grant root privileges. And, this allows to turn the process number to a string before calling the subprocess. Also, as I mentioned, use -9 (or -15 if you prefer using that). (Try to kill 1014 process too).
I found that the main process I identify with x = return.pid actually runs a child process which is the one I needed to kill, so from the parent process identified, we need to kill a child processes. The addition of "-P" includes child processes in this situation.
The following command structure is what I needed:
subprocess.call(["sudo","pkill","-9","-P",x])
Related
I have a Flask application using python3. Sometimes it create daemon process to run script, then I want to kill daemon when timeout (use signal.SIGINT).
However, some processes which created by os.system (for example, os.system('git clone xxx')) are still running after daemon was killed.
so what should I do? Thanks all!
In order to be able to kill a process you need its process id (usually referred to as a pid). os.system doesn't give you that, simply returning the value of the subprocess's return code.
The newer subprocess module gives you much more control, at the expense of somewhat more complexity. In particular it allows you to wait for the process to finish, with a timeout if required, and gives you access to the subprocess's pid. While I am not an expert in its use, this seems to
work. Note that this code needs Python 3.3 or better to use the timeout argument to the Popen.wait call.
import subprocess
process = subprocess.Popen(['git', 'clone', 'https://github.com/username/reponame'])
try:
print('Running in process', process.pid)
process.wait(timeout=10)
except subprocess.TimeoutExpired:
print('Timed out - killing', process.pid)
process.kill()
print("Done")
The following command on the command line will show you all the running instances of python.
$ ps aux | grep -i python
username 6488 0.0 0.0 2434840 712 s003 R+ 1:41PM 0:00.00 python
The first number, 6488, is the PID, process identifier. Look through the output of the command on your machine to find the PID of the process you want to kill.
You can run another command to kill the correct process.
$ kill 6488
You might need to use sudo with this command. Be careful though, you don't want to kill the wrong thing or bad stuff could happen!
I'm new to python, so here's what I'm looking to get done.
I would like to use python to manage some of my gameservers and start/stop them. For this I would like to run every gameserver in a own process.
What's the best way to create processes using python, so these processes can continue even if the main application is stopped?
To start a server I only need to execute shell code.
How can I get access after stopping my main application and restarting it to these processes?
I'm not sure if I understand the question completely, but maybe something like this?
Run process:
import subprocess
subprocess.Popen(['/path/gameserver']) #keeps running
And in another script you can use 'ps -A' to find the pid and kill (or restart) it:
import subprocess, signal
p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
out, err = p.communicate()
for line in out.splitlines():
if 'gameserver' in line:
pid = int(line.split(None, 1)[0])
os.kill(pid, signal.SIGKILL)
Check the subprocess module. There is a function called call. See here.
You may need to set the process to not be a daemon process.
I am trying to do the equivalent of the following using Python subprocess:
>cat /var/log/dmesg | festival --tts &
[1] 30875
>kill -9 -30875
Note that I am killing the process group (as indicated by the negative sign prepending the process ID number) in order to kill all of the child processes Festival launches.
In Python, I currently have the following code, wherein two processes are created and linked via a pipe.
process_cat = subprocess.Popen([
"cat",
"/var/log/dmesg"
], stdout = subprocess.PIPE)
process_Festival = subprocess.Popen([
"festival",
"--tts"
], stdin = process_cat.stdout, stdout = subprocess.PIPE)
How should I kill these processes and their child processes in a way equivalent to the Bash way shown above? The following approach is insufficient because it does not kill the child processes:
os.kill(process_cat.pid, signal.SIGKILL)
os.kill(process_Festival.pid, signal.SIGKILL)
Is there a more elegant way to do this, perhaps using just one process?
You can simplify this a lot as you rarely need cat |. Eg:
process_Festival = subprocess.Popen(["festival", "--tts", "/var/log/dmesg"])
then later
process_Festival.send_signal(1)
If you kill festival with a signal like SIGHUP rather than SIGKILL it
will clean up any subprocesses properly.
There's a very good explanation of how to create a new process group with python subprocess. Adding option preexec_fn=os.setsid to Popen:
process_Festival = subprocess.Popen(["festival", "--tts", "/var/log/dmesg"],preexec_fn=os.setsid)
You can then get the process group from the process id and signal it:
pgrp = os.getpgid(process_Festival.pid)
os.killpg(pgrp, signal.SIGINT)
Note: since Python 3.2 you can also use start_new_session=True in the Popen call instead of preexec_fn.
Environment: Raspberry Pi Wheezy
I have a python program that uses Popen to call another python program
from subprocess import *
oJob = Popen('sudo python mypgm.py',shell=True)
Another menu option is supposed to end the job immediately
oJob.kill()
but the job is still running??
When you add the option shell=True, python launches a shell and the shell in turn launches the process python mymgm.py. You are killing the shell process here which doesn't kill its own child that runs mymgm.py.
To ensure, that child process gets killed on oJob.kill, you need to group them all under one process group and make shell process, the group leader.
The code is,
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(pro.pid, signal.SIGTERM) # Send the signal to all the process groups
When you send SIGTERM signal to the shell process, it will kill all its child process as well.
You need to add a creation flag arg
oJob = Popen('sudo python mypgm.py',shell=True, creationflags = subprocess.CREATE_NEW_PROCESS_GROUP)
source
subprocess.CREATE_NEW_PROCESS_GROUP
A Popen creationflags parameter to specify that a new process group will be created. This flag is necessary for using os.kill() on the subprocess.
EDIT I agree with the comment on how to import stuff and why you are getting something is undefined. Also the other answer seems to be on the right track getting the pid
import subprocess as sub
oJob = sub.Popen('sudo python mypgm.py', creationflags = sub.CREATE_NEW_PROCESS_GROUP)
oJob.kill()
Warning Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input:
Under Linux Ubuntu operating system, I run the test.py scrip which contain a GObject loop using subprocess by:
subprocess.call(["test.py"])
Now, this test.py will creat process. Is there a way to kill this process in Python?
Note: I don't know the process ID.
I am sorry if I didn't explain my problem very clearly as I am new to this forms and new to python in general.
I would suggest not to use subprocess.call but construct a Popen object and use its API: http://docs.python.org/2/library/subprocess.html#popen-objects
In particular:
http://docs.python.org/2/library/subprocess.html#subprocess.Popen.terminate
HTH!
subprocess.call() is just subprocess.Popen().wait():
from subprocess import Popen
from threading import Timer
p = Popen(["command", "arg1"])
print(p.pid) # you can save pid to a file to use it outside Python
# do something else..
# now ask the command to exit
p.terminate()
terminator = Timer(5, p.kill) # give it 5 seconds to exit; then kill it
terminator.start()
p.wait()
terminator.cancel() # the child process exited, cancel the hit
subprocess.call waits for the process to be completed and returns the exit code (integer) value , hence there is no way of knowing the process id of the child process. YOu should consider using subprocess.Popen which forks() child process.