python,子进程:从子进程读取输出
我有以下脚本:
#!/usr/bin/python
while True:
x = raw_input()
print x[::-1]
我从 ipython 调用它:
In [5]: p = Popen('./script.py', stdin=PIPE)
In [6]: p.stdin.write('abc\n')
cba
并且它工作正常。
但是,当我这样做时:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.stdin.write('abc\n')
In [9]: p.stdout.read()
解释器挂起。我做错了什么?我希望能够多次从另一个进程写入和读取,以将一些任务传递给该进程。我需要做哪些不同的事情?
编辑1
如果我使用沟通
,我得到这个:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.communicate('abc\n')
Traceback (most recent call last):
File "./script.py", line 4, in <module>
x = raw_input()
EOFError: EOF when reading a line
Out[8]: ('cba\n', None)
编辑2
我尝试冲洗:
#!/usr/bin/python
import sys
while True:
x = raw_input()
print x[::-1]
sys.stdout.flush()
和这里:
In [5]: from subprocess import PIPE, Popen
In [6]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [7]: p.stdin.write('abc')
In [8]: p.stdin.flush()
In [9]: p.stdout.read()
但它再次挂起。
I have following script:
#!/usr/bin/python
while True:
x = raw_input()
print x[::-1]
I am calling it from ipython
:
In [5]: p = Popen('./script.py', stdin=PIPE)
In [6]: p.stdin.write('abc\n')
cba
and it works fine.
However, when I do this:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.stdin.write('abc\n')
In [9]: p.stdout.read()
the interpreter hangs. What am I doing wrong? I would like to be able to both write and read from another process multiple times, to pass some tasks to this process. What do I need to do differently?
EDIT 1
If I use communicate
, I get this:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.communicate('abc\n')
Traceback (most recent call last):
File "./script.py", line 4, in <module>
x = raw_input()
EOFError: EOF when reading a line
Out[8]: ('cba\n', None)
EDIT 2
I tried flushing:
#!/usr/bin/python
import sys
while True:
x = raw_input()
print x[::-1]
sys.stdout.flush()
and here:
In [5]: from subprocess import PIPE, Popen
In [6]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [7]: p.stdin.write('abc')
In [8]: p.stdin.flush()
In [9]: p.stdout.read()
but it hangs again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我相信这里有两个问题:
1)您的父脚本调用 p.stdout.read(),它将读取所有数据直到文件结尾。但是,您的子脚本在无限循环中运行,因此永远不会发生文件结尾。也许您想要
p.stdout.readline()
?2) 在交互模式下,大多数程序一次只缓冲一行。当从另一个程序运行时,它们缓冲更多。缓冲在许多情况下提高了效率,但当两个程序需要交互通信时会产生问题。
在
p.stdin.write('abc\n')
之后添加:在子进程脚本中,在
print x[::-1]
之后在循环中添加以下内容:(以及顶部的
import sys
)I believe there are two problems at work here:
1) Your parent script calls
p.stdout.read()
, which will read all data until end-of-file. However, your child script runs in an infinite loop so end-of-file will never happen. Probably you wantp.stdout.readline()
?2) In interactive mode, most programs do buffer only one line at a time. When run from another program, they buffer much more. The buffering improves efficiency in many cases, but causes problems when two programs need to communicate interactively.
After
p.stdin.write('abc\n')
add:In your subprocess script, after
print x[::-1]
add the following within the loop:(and
import sys
at the top)subprocess 方法 check_output 对此很有用:
output = subprocess.check_output('./script.py')
输出将是进程的标准输出。如果您也需要 stderr:
output = subprocess.check_output('./script.py', stderr=subprocess.STDOUT)
因为您避免直接管理管道,所以它可能会规避您的问题。
The subprocess method check_output can be useful for this:
output = subprocess.check_output('./script.py')
And output will be the stdout from the process. If you need stderr, too:
output = subprocess.check_output('./script.py', stderr=subprocess.STDOUT)
Because you avoid managing pipes directly, it may circumvent your issue.
如果您想将多行传递给
script.py
那么您需要同时读/写:Output:
Where
script.py
:Or
Or
If you'd like to pass several lines to
script.py
then you need to read/write simultaneously:Output:
Where
script.py
:Or
Or
您可能被 Python 的输出缓冲绊倒了。这是 python --help 对此的说明。
You're probably tripping over Python's output buffering. Here's what
python --help
has to say about it.当您完成对 p.stdin 的写入后,将其关闭:
p.stdin.close()
When you are through writing to p.stdin, close it:
p.stdin.close()
使用
communicate()
而不是.stdout.read()
。示例:
此建议来自 Popen 对象 部分http://docs.python.org/library/subprocess" rel="nofollow">子流程文档:
Use
communicate()
instead of.stdout.read()
.Example:
This recommendation comes from the Popen objects section in the subprocess documentation: