Samuel
Samuel

Reputation: 6237

How to write progressing status into file

I want to print a progressing status. I use '\r' to implement it. Following is my code

#test.py
import sys

print("beg")
for i in range(10000):  
    sys.stdout.write("\r%% %d"%((i+1)*100.0/10000))
    sys.stdout.flush()
print("\nend")

It works in the terminal. But when I redirect the output, It can't work

python test.py > log.txt

Right resolution from mhlester

import sys

tty = sys.stdout.isatty()
print('beg')
if not tty:  
    position = sys.stdout.tell()                # get position
for i in range(10000):
    if tty:                                 # use falsetru's answer here
        sys.stdout.write('\r%% %d'%((i+1)*100.0/10000))# as you were before
    else:
        print('of')
        sys.stdout.seek(position)                  # or seek to position
        sys.stdout.write('%% %d'%((i+1)*100.0/10000))
    sys.stdout.flush()
print('\nend')

Upvotes: 0

Views: 67

Answers (2)

mhlester
mhlester

Reputation: 23221

It won't work for stdout, but it will work if you write to a file. Instead of \r, you need to seek() to the right position in the file. To find out the position you're at in the file, use tell()

    sys.stdout.write('beg')
    position = sys.stdout.tell()                # get position
    for i in range(10000):
        if tty:                                 # use falsetru's answer here
            print '\r',                         # as you were before
        else:
            out.seek(position)                  # or seek to position
        out.write('%% %d'%((i+1)*100.0/10000))
        out.flush()
    out.write('\nend')

Edited to work both ways

Upvotes: 1

falsetru
falsetru

Reputation: 369064

Writing \r to the file behave different with writing it to the terminal.

It write byte 13 (0x0d) to the file instead of moving cursor.

You'd better check a stream is tty or not, then do different thing according to that.

>>> sys.stdout.isatty()
True

Upvotes: 1

Related Questions