1

我有一个脚本parent.py试图从sub.pyPython 的子进程中读取标准输出。

家长parent.py

#!/usr/bin/python
import subprocess
p = subprocess.Popen("sub.py", stdout=subprocess.PIPE)
print p.stdout.read(1)

和子进程sub.py

#!/usr/bin/python
print raw_input( "hello world!" )

我希望运行parent.py从“hello world!”打印“h”。实际上,它挂了。我只能通过添加-usub.py's she-bang 行来获得我的预期行为。

这让我感到困惑,因为当直接从 shell 运行-u时,开关没有区别。sub.pyparent.py.

我的目标是将 C 程序作为子进程运行,因此我将无法控制它是否刷新标准输出。为什么 shell 比从 运行相同的东西的 Python 可以更好地访问进程的标准输出subprocess.Popen?我是否能够从不刷新其缓冲区的 C 程序中读取这样的标准输出流?

编辑:

这是基于 korylprince 评论的更新示例...

## capitalize.sh ##
#!/bin/sh

while [ 1 ]; do
    read s
    echo $s | tr '[:lower:]' '[:upper:]'
done

########################################

## parent.py ##
#!/usr/bin/python 
from subprocess import Popen, PIPE

# cmd = [ 'capitalize.sh' ] # This would work
cmd = [ 'script', '-q', '-f', '-c', 'capitalize.sh', '/dev/null']

p = Popen(cmd, stdin=PIPE)
p.stdin.write("some string\n")
p.wait()

运行时script,我会稳定打印换行符(如果这是一个 Python 子进程,它会引发 EOFerror)。

4

2 回答 2

1

另一种选择是

p = subprocess.Popen(["python", "-u", "sub.py"], stdout=subprocess.PIPE)

这里的建议。

我的经验是,是的,您无需任何额外的努力就可以阅读大多数 C 程序。

Python 解释器需要额外的步骤来缓冲其输出,这就是它需要-u开关来禁用输出缓冲的原因。您的典型 C 程序不会这样做。

除了我期望工作并且不在子shell中的Python解释器之外,我没有遇到任何程序(C或其他)。

于 2012-09-28T02:33:43.160 回答
0

无论“-u”如何,shell 都可以立即读取输出的原因是因为您从 shell 启动的程序的输出连接到 TTY。当 stdout 连接到 TTY 时,它是无缓冲的(因为它由 TTY 来缓冲)。当你从 python 中启动 python 子进程时,你正在将 stdout 连接到一个管道,这意味着你可以在子进程想要的时候刷新它的输出。

如果您希望与子流程进行复杂的交互,请查看本教程。

于 2012-10-01T15:33:18.897 回答