4

I need to read output, line by line, of a program that uses carriage returns (\r) to make its output. The program runs for a long time, so I need to read the output as the program runs. I know how to do this when each item of output appears on a new line (as detailed here), but I can't seem to get it to work with carriage returns.

Here is the code I used to try and get it to work (run on a linux system)

import subprocess

command = ["printf", "".join(["Return count: " + str(x) + "\\r" for x in range(10)]) + "\n"]
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
buf = bytearray()
out = proc.stdout
while True:
    c = out.read()
    if c == b"":
        break
    if c == "\r":
        print(buf)
        buf = bytearray()
    else:
        buf += c

print("Done")

However the code simply exits immediately, printing Done.

I want the code to print:

Return code: 1
Return code: 2
Return code: 3

etc. What do I need to modify to get this to work?

DonyorM
  • 1,760
  • 1
  • 20
  • 34

1 Answers1

3

If you want to get byte by byte you need to pass a number of bytes to get to read method:

c = out.read(1)

Otherwise, it will read whole content.

falsetru
  • 357,413
  • 63
  • 732
  • 636
  • To read the output line-by-line, wouldn't one want to use `for line in out:`? – martineau Dec 04 '16 at 17:12
  • 1
    @martineau Because it's delimited by carriage returns not newlines. You know how some terminal programs (like apt-get's progress bar) update the line in place. I'm dealing with a program that does that. – DonyorM Dec 05 '16 at 01:56