【问题标题】:Asynchronously read stdout from subprocess.Popen从 subprocess.Popen 异步读取标准输出
【发布时间】:2010-12-21 18:56:57
【问题描述】:

我正在使用 subprocess.popen 运行一个子程序。当我从命令窗口 (cmd.exe) 启动我的 Python 程序时,随着程序的发展,程序会在窗口中写入一些信息和日期。

当我在命令窗口中运行我的 Python 代码 not 时,它会为此子程序的输出打开一个新的命令窗口,我想避免这种情况。当我使用以下代码时,它没有显示 cmd 窗口,但也没有打印状态:

p = subprocess.Popen("c:/flow/flow.exe", shell=True, stdout=subprocess.PIPE)
print p.stdout.read()

如何在我的程序输出中显示子程序的输出?

【问题讨论】:

  • "windows 窗口" 什么Windows 窗口?您使用的是 GUI 框架吗?哪一个?
  • 好吧,我正在通过 arcgis 运行模型。当我单击我在那里创建的工具时,会出现一个窗口并显示进度。我想看到命令窗口中出现的行。
  • 还有,对维基感到抱歉。我没有肉点击那个选项。
  • python3 w/ asyncio 这就是你想要的:kevinmccarthy.org/2016/07/25/…

标签: python windows subprocess


【解决方案1】:

使用这个:

cmd = subprocess.Popen(["c:/flow/flow.exe"], stdout=subprocess.PIPE)
for line in cmd.stdout:
    print line.rstrip("\n")
cmd.wait()  # you may already be handling this in your current code

请注意,您仍然需要等待子程序刷新其标准输出缓冲区(通常在不写入终端窗口时缓冲不同),因此您可能不会在子程序打印时立即看到每一行它(这取决于各种操作系统细节和子程序的细节)。

还要注意我是如何删除 shell=True 并将字符串参数替换为列表的,这通常是推荐的。

【讨论】:

  • 替代“line.rstrip..”,您可以使用“line,”(注意尾随逗号)
  • for line in iter(cmd.stdout.readline, ""): print line, 可能会通过避免文件迭代器中的预读缓冲区来提供更直接的输出(注意:子程序仍然必须刷新其标准输出)
  • 不明白为什么这是异步的。
【解决方案2】:

寻找异步处理 Popen 数据的方法我偶然发现了http://code.activestate.com/recipes/576759-subprocess-with-async-io-pipes-class/

这看起来很有希望,但我的印象是其中可能有一些错别字。还没试过。

【讨论】:

    【解决方案3】:

    这是一个旧帖子,但是一个很难找到解决方案的常见问题。试试这个:http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/

    【讨论】:

    • 不幸的是这个解决方案没有异步。