我正在尝试做一个使用子流程包的非常简单的示例。 python脚本应打开一个新进程并运行read
命令。 read
命令应通过PIPE接收来自stdin的输入。每当我尝试使用write()
和flush()
时,都会说:
Traceback (most recent call last):
File "recorder.py", line 68, in <module>
p.stdin.flush()
BrokenPipeError: [Errno 32] Broken pipe
我的python代码如下:
import subprocess
import time
p = subprocess.Popen(
[
"read",
],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
bufsize=1
)
for character in "This is the message!\n":
p.stdin.write(character.encode("utf-8"))
time.sleep(0.25)
p.stdin.flush()
assert p.returncode == 0
注意:一个字符接一个字符发送(睡眠超时)非常重要。
答案 0 :(得分:1)
我实际上无法复制您的结果*,在我的情况下,您的循环运行了,由于assert
尚未完成并且还没有p
({或当时的值仍为returncode
)。在循环之后和None
之前插入p.wait()
将迫使我们仅在assert
终止之后检查结果。
现在,对于您所看到的异常,它很可能表明您尝试对其执行p
的管道已关闭。最有可能是由于该进程已经终止。也许在您的情况下,它也已经有一个(非零)flush()
,可以进一步帮助您理解问题?**
*在我的系统上,returncode
与/bin/sh
一起使用的subprocess.Popen()
实际上是shell=True
。运行bash
(大概是您系统上的["/bin/dash", "-c", "read"]
的shell调用),我也遇到了断线的情况。
**像这样运行破折号似乎失败了:
/bin/sh
并返回/bin/dash: 1: read: arg count
。
哪种方式使问题更加棘手:为什么调用2
(从/bin/dash -c "read"
)失败。似乎破折号python
(不同于其bash副本)总是期望至少有一个变量名作为参数读入(用read
代替read
)。
我想这个python问题只是关于假设和shell脚本可移植性的一课。 :)