Real time output of subprocess.popen() and not line by line

一笑奈何 提交于 2020-01-02 05:09:49

问题


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++ ?


回答1:


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.




回答2:


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.




回答3:


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',


来源:https://stackoverflow.com/questions/4620547/real-time-output-of-subprocess-popen-and-not-line-by-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!