I am trying to run a Python script from another Python script, and getting its pid
so I can kill it later.
I tried subprocess.Popen()
with argument shell=True', but the
pidattribute returns the
pid` of the parent script, so when I try to kill the subprocess, it kills the parent.
Here is my code:
proc = subprocess.Popen(" python ./script.py", shell=True)
pid_ = proc.pid
.
.
.
# later in my code
os.system('kill -9 %s'%pid_)
#IT KILLS THE PARENT :(
Description. Python method popen() opens a pipe to or from command. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'.
DESCRIPTION top. The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read- only or write-only.
subprocess. check_call() gets the final return value from the script, and 0 generally means "the script completed successfully".
Popen is more general than subprocess. call . Popen doesn't block, allowing you to interact with the process while it's running, or continue with other things in your Python program. The call to Popen returns a Popen object.
shell=True
starts a new shell process. proc.pid
is the pid of that shell process. kill -9
kills the shell process making the grandchild python process into an orphan.
If the grandchild python script can spawn its own child processes and you want to kill the whole process tree then see How to terminate a python subprocess launched with shell=True:
#!/usr/bin/env python
import os
import signal
import subprocess
proc = subprocess.Popen("python script.py", shell=True, preexec_fn=os.setsid)
# ...
os.killpg(proc.pid, signal.SIGTERM)
If script.py
does not spawn any processes then use @icktoofay suggestion: drop shell=True
, use a list argument, and call proc.terminate()
or proc.kill()
-- the latter always works eventually:
#!/usr/bin/env python
import subprocess
proc = subprocess.Popen(["python", "script.py"])
# ...
proc.terminate()
If you want to run your parent script from a different directory; you might need get_script_dir()
function.
Consider importing the python module and running its functions, using its object (perhaps via multiprocessing
) instead of running it as a script. Here's code example that demonstrates get_script_dir()
and multiprocessing
usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With