Python: Getting live output from subprocess using poll

python-logoUsing subprocess.Popen, subprocess.call, or subprocess.check_output will all invoke a process using Python, but if you want live output coming from stdout you need use subprocess.Popen in tandem with the Popen.poll method.

In this article I will show how to invoke a process from Python and show  stdout live without waiting for the process to complete.  This is a better end-user experience for longer running jobs.

Example long-running command

As an example of a long running command, consider the Bash script loopWithSleep.sh which I’ve uploaded to github.  Below is the full script:

#!/bin/bash

for i in $(seq 1 5); do
   echo "iteration" $i
   sleep 1
done

Every second it displays a line of output and takes a total of 5 seconds to run.

iteration 1
iteration 2
iteration 3
iteration 4
iteration 5

Python Popen.poll()

If you start a process using process.call() or process.check_output(), then you cannot get the output until the process is compete.  However if you use subprocess.Popen along with Popen.poll() to check for new output, then you see a live view of the stdout.

# invoke process
process = subprocess.Popen(shlex.split(command),shell=False,stdout=process.PIPE)

# Poll process.stdout to show stdout live
while True:
  output = process.stdout.readline()
  if process.poll() is not None:
    break
  if output:
    print output.strip()
rc = process.poll()

Example Program

For an example that pulls all this together, see my runProcessWithLiveOutput.py on github.   Download this into the same directory as the Bash loopWithSleep.sh as an example program.

$ ./runProcessWithLiveOutput.py
Execute which commmand [./loopWithSleep.sh]: 
== invoke_process_popen_blocking ==============
iteration 1
iteration 2
iteration 3
iteration 4
iteration 5

== invoke_process_popen_poll_live ==============
iteration 1
iteration 2
iteration 3
iteration 4
iteration 5

You then get an example of how subprocess.communicate() does not show the output until the subprocess is complete.  However using poll, you get the ouput in real-time.

 

REFERENCES

python docs reference

endpoint, realtime output from subprocess

stackoverflow, Popen and streaming

pythonspot, subprocess.popen, call, and check_output