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>I think the <a href="http://linux.die.net/man/1/timeout" rel="nofollow"><code>timeout</code></a> command is perfect for you. From the doc page:</p>

<blockquote>
  <h2>Synopsis</h2>
  
  <p><strong>timeout</strong> <em>[OPTION] NUMBER[SUFFIX] COMMAND [ARG]...</em><br/>
  <strong>timeout</strong> <em>[OPTION]</em></p>
  
  <hr>
  
  <h2>Description</h2>
  
  <p>Start COMMAND, and kill it if still running after NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.</p>
  
  <p><strong>-s</strong>, <strong>--signal</strong>=<em>SIGNAL</em><br/>
  specify the signal to be sent on timeout.<br/>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>SIGNAL</em> may be a name like 'HUP' or a number.<br/>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;See 'kill -l' for a list of signals </p>
</blockquote>

<p>By depending on <code>timeout</code>, you don't have to worry about the messy details of PID reuse, race conditions, etc. Those concerns are nicely encapsulated in this standard Unix utility. Another benefit is your script will resume execution immediately upon early termination by the subprocess, rather than needlessly sleeping for the full 10 seconds.</p>

<p>Demo in bash:</p>

<pre><code>timeout -s9 10 sleep 11; echo $?;
## Killed
## 137
timeout -s9 10 sleep 3; echo $?;
## 0
</code></pre>

<p>Demo in python:</p>

<pre><code>import subprocess;
subprocess.Popen(['timeout','-s9','10','sleep','11']).wait();
## -9
subprocess.Popen(['timeout','-s9','10','sleep','3']).wait();
## 0
</code></pre>

python linux bash process psutil