Taken from http://stackoverflow.com/a/31867499 with some modifications.
import logging
from subprocess import Popen, PIPE
from threading import Thread
from Queue import Queue
def reader(pipe, queue):
try:
with pipe:
for line in iter(pipe.readline, b''):
queue.put((pipe, line))
finally:
# Descriptor was closed. Signal this to the consumer of
# the queue
queue.put(None)
command = [
'/bin/bash',
'-c',
'echo "stdout 1"; sleep 1; >&2 echo "stderr 1"; sleep 1; echo "stdout 2"; sleep 1; >&2 echo "stderr 2"',
]
process = Popen(command, stdout=PIPE, stderr=PIPE, bufsize=1)
q = Queue()
Thread(target=reader, args=[process.stdout, q]).start()
Thread(target=reader, args=[process.stderr, q]).start()
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Since we have two descriptors - we are expecting two
# signals (None value) on the queue
for _ in range(2):
for source, line in iter(q.get, None):
if source == process.stdout:
logger.info(line.rstrip())
elif source == process.stderr:
logger.error(line.rstrip())