Real time output of subprocess.popen() and not lin

2019-05-07 03:53发布

I'm currently rewriting a little wrapper program in python that I once wrote in C++. It extracts files from a file and boxes them in another format.

In C++ the output from the system commands I need to run was "real time" i.e the status bar and the percentage indicator of some commands where shown in real time. With python I get each 'percent' dumped on the screen individually (because I read it line by line). Here's an example: Thats how a status bar looks in the python version (this goes on until 100). In C++ it does update itself though.

| (02/100)\rImporting AVC-H264: |                    | (03/100)\rImporting AVC-H264: |                       | (04/100)\rImporting AVC-H264: |=

Thats the corresponding python code:

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for line in iter(p.stdout.readline, ""):
   print line,

Any ideas on how I could make it look like in C++ ?

3条回答
孤傲高冷的网名
2楼-- · 2019-05-07 04:11

Sorry but i didn't understand well the real time part, but maybe i can help with "update it self" part, try this:

for line in iter(p.stdout.readline, ""):
   print line + '\r',
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-05-07 04:14

On Windows, you can output the backspace character (ASCII code 8). Example (prints the current iteration using only single digit numbers):

>>> import time
>>> import sys
>>> for i in xrange(10):
...     sys.stdout.write(str(i))
...     time.sleep(.5)
...     sys.stdout.write(chr(8))
...

You would need to keep track of the number of characters on the current line... I'm sure there must be a better way.

On Linux, it appears that you can write carriage returns to reset the cursor position. See Erase the current printed console line and In-place progress output in the terminal or console.

查看更多
Fickle 薄情
4楼-- · 2019-05-07 04:23

Could be two things...

It's likely that readline is changing some things from the output of your program. I believe \r is carriage return and tells the terminal to return to the beginning of the line and then the program can output overtop the text it just output. Readline is most likely removing this.

First thing to try,

p = subprocess.Popen(args, stdout=subprocess.PIPE, \
                     stderr=subprocess.PIPE, \
                     universal_newlines=True)
for line in iter(p.stdout.readline, ""):
    sys.stdout.write('\r'+line[:-1])
    sys.stdout.flush()

You have to do the flush because stdout buffers until it gets a \n and of course you're not writing one.

查看更多
登录 后发表回答