0

I followed the accepted answer for this question A non-blocking read on a subprocess.PIPE in Python to read non-blocking from a subprocess. This generally works fine, except if the process I call terminates quickly. This is on Windows.

To illustrate, I have a bat file that simply writes one line to stdout:

test.bat:

 @ECHO OFF
 ECHO Fast termination

And here the python code, adapted from above mentioned answer:

from subprocess import PIPE, Popen
from threading  import Thread
from queue import Queue, Empty


def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p = Popen(['test.bat'], stdout=PIPE, bufsize=-1, 
          text=True)

q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

output = str()
while True:
    try:
        line = q.get_nowait()
    except Empty:
        line = ""
    output += line
    if p.poll() is not None:
        break

print(output)

Sometimes, the line from the bat file is correctly captured and printed, sometimes nothing is captured an printed. I suspect that the subprocess might finish before the thread connects the queue to the pipe, and then it doesn't read anything. If I add a little wait of 2 seconds in the bat file before echoing the line, it seems to always work. Likewise the behavior can be forced by adding a little sleep after the Popen in the python code. Is there a way to reliably capture the output of the subprocess even if it finishes immediately while still doing a non-blocking read?

Soeren D.
  • 264
  • 1
  • 6

0 Answers0