简体   繁体   English

从子进程读取的实时stdout仅在从PyCharm运行而不在Terminal运行时有效

[英]Real-time stdout read from subprocess works only when running from PyCharm and not Terminal

What the application does: runs a subprocess and displays the stdout in real-time to a Tkinter textbox widget. 应用程序的作用:运行一个子进程,并向Tkinter文本框小部件实时显示标准输出。

This works perfectly when I run the application from PyCharm. 当我从PyCharm运行应用程序时,此方法非常有效。

When I run the application from terminal ./application.py it doesn't display in real-time, but instead will display it all after the process has finished. 当我从终端./application.py运行应用程序时,它不会实时显示,而是在处理完成全部显示。


Some details: 一些细节:

I have a subprocess running (the subprocess prints out "SPAM" every 1 second for 10 seconds): 我有一个正在运行的子流程(该子流程每1秒打印出“ SPAM”,持续10秒):

process = subprocess.Popen(<some file path>, stdout=subprocess.PIPE, universal_newlines=True)

I am printing the stdout to a Tkinter textbox widget: 我将标准输出打印到Tkinter文本框小部件:

for stdout_line in iter(process.stdout.readline, ""):
     self.app.pm_textbox.see(tk.END)
     self.app.pm_textbox.insert(tk.INSERT, stdout_line)

So my question is what could possibly cause running from terminal and PyCharm to display stdout data differently? 所以我的问题是什么可能导致从终端和PyCharm运行以不同方式显示stdout数据?

I know this is an old thread, but still - 我知道这是旧线程,但仍然-

I had the same issue as you did. 我和你有同样的问题。 I asked a question that seemed to help me get in the right direction as to working with real time output. 我问了一个问题 ,似乎可以帮助我朝着正确的方向进行实时输出。 My issue was I needed to differentiate output that resulted of a CR and simulate that behavior in my program. 我的问题是我需要区分CR产生的输出并在程序中模拟该行为。 But then I encountered your problem as well - I worked for 3 days trying to find a solution as to why this happens. 但是后来我也遇到了您的问题-我花了3天的时间试图找到解决此问题的方法。

After reading this and having no luck with what they did there, I found this thread without answers but one comment that after a little modification, finally helped me. 读完这篇文章并且对他们所做的一切感到不走运之后,我发现此主题没有答案,但有一条评论说,经过一些修改,终于对我有所帮助。

What finally worked for me, is this: 最终对我有用的是:

#                        This seems to handle    This seems to handle
#                        the terminal output     the PyCharm output
proc = subprocess.Popen(["stdbuf", "-oL"] + cmd, stdout=subprocess.PIPE)

out = io.open(proc.stdout.fileno(), mode='r', encoding="utf-8", newline='')
should_cr = False
for line in out:
    if should_cr is True:
        sys.stdout.write("\r")
        sys.stdout.flush()

    if line.endswith(os.linesep):
        should_cr = False
        sys.stdout.write(line)
        sys.stdout.flush()

    elif line.endswith("\r"):
        should_cr = True
        line = line.rstrip()
        sys.stdout.write(line)
        sys.stdout.flush()

If you wouldn't regard CR output then it is more simple of course: 如果您不考虑CR输出,那么它当然会更简单:

#                        This seems to handle    This seems to handle
#                        the terminal output     the PyCharm output
proc = subprocess.Popen(["stdbuf", "-oL"] + cmd, stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
    print(line)

Notice this works for me in Python 2.7 请注意,这在Python 2.7中对我有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM