I'm trying to print out status updates (e.g., the line number that my program is on) that overwrite the previous update on the same line of the console output. Most Stack Overflow answers about this advise to use '\r'. The following code works great on my Windows computer:
import time
for i in range(10):
print str(i) + '\r' ,
time.sleep(1)
But when I move it to a Google Compute Engine machine (Debian GNU/Linux 7.8 (wheezy)), this same code doesn't display any output. Any ideas why?
This is probably a buffering problem -- discussion follows.
Buffer flushing works differently depending on the kind of file or pipe attached. This is to support showing a human what he needs to see in a timely fashion, while still handling file operations more efficiently by batching things up where appropriate. But sometimes the algorithm gets it wrong; fortunately the tools are there to manually flush when this happens:
from sys import stdout
import time
for i in range(10):
print str(i) + '\r' ,
stdout.flush()
time.sleep(1)
As an aside, I personally find it annoying when the cursor is on top of my string, so if I am doing something like this I will usually start off with a space:
print ' %s\r' % i,
Alternatively, since you need to import sys and have stdout available anyway, you can dispense with the funny comma after the print, and just do this:
stdout.write(' %s\r' % i)
Some more information of buffering of stdin, stdout, and stderr is discussed here:
Is stdout line buffered, unbuffered or indeterminate by default?
Note that stderr is not usually buffered, so usually won't have this problem. Directing status information to stderr and actual output to stdout is a great way to have your cake and eat it too for simple programs -- you can either view everything on the screen, or you can redirect stdout to a file or pipe for later processing, and still see the status information during program execution.