Python Popen().stdout.read() 卡住了

15
我正在尝试使用Python的subprocess.Popen获取另一个脚本的输出,方法如下:

我用Python的subprocess.Popen来获取另一个脚本的输出,具体操作如下:

process = Popen(command, stdout=PIPE, shell=True)
exitcode = process.wait()
output = process.stdout.read()   # hangs here

当我将它作为Python脚本运行时,它卡在第三行,但在Python shell中无法复现此问题。

另一个脚本仅打印了几个单词,我认为这不是缓冲区问题。

有人知道我在这里做错了什么吗?


如果你手动运行command命令,它会生成输出吗? - Some programmer dude
3个回答

5
你可能想使用 .communicate() 而不是 .wait() 加上 .read()。请注意有关 subprocess 文档页面中 wait() 的警告:

警告 当使用 stdout=PIPE 和/或 stderr=PIPE 并且子进程生成足够的输出以使管道阻塞等待 OS 管道缓冲区接受更多数据时,这将导致死锁。使用 communicate() 来避免这种情况。

http://docs.python.org/2/library/subprocess.html#subprocess.Popen.wait


谢谢你的回答。我刚刚意识到我已经阅读了文档中的那一部分。当脚本运行时,我正在使用while process.poll() is None:循环实时获取stdout,并且上面的代码是一个简化版本。但我猜想它挂起的原因是类似的死锁问题... - lyomi
嗯,这对我没用,它仍然卡住了。 - CrazyVideoGamer

0

read() 在返回之前等待 EOF。

您可以:

  • 等待子进程死亡,然后 read() 将会返回。
  • 如果输出被分成几行,则使用 readline()(如果没有输出行仍将挂起)。
  • 使用 os.read(F, N),它从 F 中返回最多 N 个字节,但如果管道为空,它仍将阻塞(除非在 fd 上设置了 O_NONBLOCK)。

-1

你可以在下面的资源中了解如何处理stdout/stderr的挂起读取:

readingproc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接