subprocess.Popen与CLI提示交互

时间:2017-12-22 23:38:09

标签: python bash subprocess command-line-interface popen

我正在尝试使用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>

我想做什么:

而不是使用p.stdin.write("5+5") out1 = p.stdout.read() p.stdin.write("5*10") out2 = p.stdout.read() 。我希望能够发送单个命令并读取立即输出。例如,我想这样做:

out1

因此out2应为5,stdout应为50。

问题:

在关闭stdin之前,您无法阅读read(n)

你是怎么做到的?我无法使用readline()A B C D E F G H I J E1 40 1 4 4/16/2017 E4 30 11/1/2017 E2 20 1 5 6/22/2016 E2 20 11/1/2017 E3 10 0 4 6/30/2017 E1 40 10/31/2017 E4 30 1 6 3/10/2015 E3 10 10/31/2017 ,因为在我的实际应用中,我不知道输出的长度。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

通过一些小修改,我能够从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\n")
7
>>> fr.read()
'\nIn [1]: Out[1]: \n5000\n'
>>> p.stdin.write("2/3.\n")
5
>>> fr.read()
'\nIn [2]: Out[2]: \n0.6667\n'

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

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