I have the following problem:
I need my Python script run a bash script. In case the bash script is running more than let's say 10 seconds, I need to kill it. This is what I have so far:
cmd = ["bash", "script.sh", self.get_script_path()]
process = subprocess.Popen(cmd)
time.sleep(10) # process running here...
procinfo = psutil.Process(process.pid)
children = procinfo.children(recursive=True)
for child in children:
os.kill(child.pid, signal.SIGKILL)
The thing I am afraid of is this scenario: The bash script finishes in 1 second, frees its PID and the system passes the PID to another process. After 10 seconds, I kill the PID which I think it belongs to my script but it is not true and I kill some other process. The script needs to be run as root because I require chroot
in it.
Any ideas?
Since you are already using psutil
I suggest you replace the calls to the subprocess
module with calls to psutil.Popen
. This class has the same interface of subprocess.Popen
but provides all the functionality of psutil.Process
.
Also note that the psutil
library pre-emptively checks for PID reuse already, at least for a number of methods including terminate
and kill
(just read the documentation for Process
).
This means that the following code:
cmd = ["bash", "script.sh", self.get_script_path()]
process = psutil.Popen(cmd)
time.sleep(10) # process running here...
children = process.children(recursive=True)
for child in children:
child.terminate() # try to close the process "gently" first
child.kill()
Note that the documentation for children
says:
children(recursive=False)
Return the children of this process as a list of
Process
objects, preemptively checking whether PID has been reused.
In summary this means that:
children
the psutil
library checks that you want the children of the correct process and not one that happen to have the same pidterminate
or kill
the library makes sure that you are killing your child process and not a random process with the same pid.