Check if a process is still running
<p>I have the following problem:</p>

<p>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:</p>

<pre><code>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)
</code></pre>

<p>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 <code>chroot</code> in it.</p>

<p>Any ideas?</p>

<p>Since you are already using <code>psutil</code> I suggest you replace the calls to the <code>subprocess</code> module with calls to <a href="http://pythonhosted.org/psutil/#psutil.Popen" rel="nofollow"><code>psutil.Popen</code></a>. This class has the same interface of <code>subprocess.Popen</code> but provides all the functionality of <code>psutil.Process</code>.</p>

<p>Also note that <strong>the <code>psutil</code> library pre-emptively checks for PID reuse already</strong>, at least for a number of methods including <code>terminate</code> and <code>kill</code> (just read the <a href="http://pythonhosted.org/psutil/#psutil.Popen" rel="nofollow">documentation for <code>Process</code></a>).</p>

<p>This means that the following code:</p>

<pre><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()
</code></pre>

<p>Note that the documentation for <code>children</code> says:</p>

<blockquote>
  <p><strong>children(recursive=False)</strong></p>
  
  <p>Return the children of this process as a list of <code>Process</code> objects, <strong>preemptively checking whether PID has been reused.</strong></p>
</blockquote>

<p>In summary this means that:</p>

<ol>
<li>When you call <code>children</code> the <code>psutil</code> library checks that you want the children of the correct process and not one that happen to have the same pid</li>
<li>When you call <code>terminate</code> or <code>kill</code> the library makes sure that you are killing your child process and not a random process with the same pid.</li>
</ol>

python linux bash process psutil