subprocess.Popen与CLI提示交互

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了subprocess.Popen与CLI提示交互相关的知识,希望对你有一定的参考价值。

我正在尝试使用subprocess.Popen编写和读取CLI程序。

因此,每次向CLI发出命令时,它都会打印一些内容,而这正是我想要读取的内容。我将尝试用一个具体的例子来解释我想做什么,这样每个人都可以尝试。

因此,我将使用my real program代替使用ipython问题:

p = subprocess.Popen(['ipython'],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate(input="5+5")

如果你使用Popen.communicate(input=command),你可以在stdout上获得ipython将在终端中打印的所有文本,如果我直接从shell执行它。

我想做的事:

而不是使用communicate。我希望能够发送单个命令并读取立即输出。例如,我想做:

p.stdin.write("5+5")
out1 = p.stdout.read()

p.stdin.write("5*10")
out2 = p.stdout.read()

所以out1应该是5,而out2应该是50。

问题:

在关闭stdout之前,你不能阅读stdin

你是怎样做的 ?我不能使用read(n)readline(),因为在我的实际应用中我不知道输出的长度。

答案

调用communicate()块直到进程退出,这不是你想要的。你需要阅读p.stdout并写信给p.stdin

或者,您可能会发现pexpect模块很有用。

另一答案

通过一些小的修改,我能够从this question工作的方法。

使用Python3:

>>> from subprocess import Popen, PIPE
>>> 
>>> fw = open("tmpout", "wb")
>>> fr = open("tmpout", "r")
>>> p = Popen("ipython", stdin=PIPE, stdout=fw, stderr=fw, bufsize=1, universal_newlines=True)
>>> header = fr.read()
>>> p.stdin.write("100*50
")
7
>>> fr.read()
'
In [1]: Out[1]: 
5000
'
>>> p.stdin.write("2/3.
")
5
>>> fr.read()
'
In [2]: Out[2]: 
0.6667
'

如您所见,它以交互方式工作。

一个技巧是,在Py3下,bufsize=1仅在universal_newlines=True时才进行I / O线缓冲。

以上是关于subprocess.Popen与CLI提示交互的主要内容,如果未能解决你的问题,请参考以下文章

当从 Django 内部调用时,Subprocess.Popen 与交互式程序一起挂起

subprocess模块

subprocess模块

subprocess.call() 与 GUI (Tkinter) 交互

Python中subprocess学习

Python中subprocess学习