python - 如何将输入流式传输到 python Popen 子进程并从中流式输出?
问题描述
我正在尝试使用subprocess.Popen
. 作为用于测试目的的样板代码,这就是我所拥有的:
if __name__ == '__main__':
ps = subprocess.Popen(
input('command? '),
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
print(ps.stdout.read())
time.sleep(1) # provide enough time to register completion if the command is a one-off, like dir or echo
while ps.poll() == None: # ps.poll() returns None if still running
try:
# method one
ps.stdin.write(input())
ps.communicate()
print(ps.stdout.read())
# method two
ps.stdin.write(input())
print(ps.communicate()[0])
# method three
print(ps.communicate(input())[0])
except:
continue
print('Process Finished')
每种方法都是不同的(失败的)尝试。
对于python
应该打开 python CLI 解释器的命令,这完全失败了。但是,对于一次性命令,例如dir
甚至ls
运行python -c "<some python>"
它就可以了。
命令行日志:
C:\Users\nj2u2\Desktop\test>python test.py
command? echo hello
hello
Process Finished
C:\Users\nj2u2\Desktop\test>python test.py
command? dir
Volume in drive C has no label.
Volume Serial Number is D6B7-6B8D
Directory of C:\Users\nj2u2\Desktop\test
07/03/2020 12:26 AM <DIR> .
07/03/2020 12:26 AM <DIR> ..
07/03/2020 08:20 PM 6,811 subprocess_plus.py
07/04/2020 12:55 PM 580 test.py
07/03/2020 08:25 PM <DIR> __pycache__
2 File(s) 7,391 bytes
3 Dir(s) 1,487,446,302,720 bytes free
Process Finished
C:\Users\nj2u2\Desktop\test>python test.py
command? python
在最后一个命令之后python
,它只是挂在print(ps.stdout.read())
.
我想知道它为什么挂起,以及如何修复它。
解决方案
该communicate
方法只能用于非交互式命令,因为它发送一次性输入,然后等待子进程终止。这就是它只能与你所说的一次性命令一起工作的原因。
但要注意,管道不支持终端规则,其中读取调用自动刷新输出,并且新行导致读取立即返回。因此,没有任何东西可以保证您可以使用它来为 python CLI 解释器提供交互式 IO。管道只是流,可以缓冲,因此您可以确保所有输入都将被传递,并且当输出通道关闭时(即当子流程命令终止时)您将收到所有输出。输入和输出混合的方式取决于子流程命令的编程方式。如果它愿意在读取之前刷新其输出,并且您在代码中执行相同操作,那么交互式处理是可能的,但如果不这样做,则无法期望在每行结束后收到一些东西。
推荐阅读
- sqlite - Flutter 删除sqlite表中的所有数据,然后插入记录
- express - 当有多个套件时,Jest 不显示测试
- c# - 如何将复选框绑定到可为空的字节字段?
- javascript - 使用jQuery获取和替换div背景图片url
- swift - 无法使用在 OSX 10.14 中工作的代码在 OSX 10.15 中制作金属纹理
- javascript - 如何使用 Javascript 链接到另一个页面并在该新页面上执行操作?
- python - 当我有多个不同长度的字符串时,有没有办法将一个字符放在所有字符串的相同索引处
- java - VFS FileObject 无法删除文件
- python - GroupBy Power Query 结果与 pandas.groupby 结果不匹配?
- docker - 如何使用 Docker 中的 DNS 来引用相同 DN 的所有复制容器?