如何使用子进程与python脚本进行交互

时间:2016-08-09 19:09:14

标签: python python-3.x subprocess python-3.4 popen

我在python中编写了一个用于python的IDE,并且需要使用子进程来与用户的脚本进行交互。

我对使用子进程完全不熟悉并且不确定我在这里做了什么。我创建了一个测试代码段,代表我尝试做的事情:

from subprocess import Popen,PIPE,STDOUT
import tkinter as tk

t=tk.Text()
t.pack()

p = Popen(["python","c:/runme.py"],stdout=PIPE,stdin=PIPE,stderr=PIPE,shell=True)
p.stdin.write("5".encode())
out=p.stdout.read()

t.insert(1.0,out)

以下是我试图与之互动的测试脚本:

print("Hello World")
inp=input("Enter a Number: ")
print(inp)
quit()

不幸的是它只是在第2行等待(大概)。如何阅读已经打印的内容以及如何输入字符串?

3 个答案:

答案 0 :(得分:2)

您必须定期刷新stdout,因为如果脚本未连接到终端,则不会自动刷新输出:

import sys
print("Hello World")
print("Enter a Number: ")
stdout.flush()
inp = input()
print(inp)

并且您必须通过返回\n终止输入:

p = Popen(["python", "c:/runme.py"], stdout=PIPE, stdin=PIPE, stderr=PIPE)
p.stdin.write("5\n".encode())
out = p.stdout.read()

答案 1 :(得分:2)

删除shell=True 。目前,您根本没有 执行脚本,只是启动python交互式解释器。

问题在于when you use shell=True the way in which the first argument is interpreted changes.您不需要shell=True,并且您提供的参数对于shell=False版本是正确的。

看到之间的区别:

>>> import subprocess
>>> subprocess.Popen(['python', 'whatever'], shell=True)
<subprocess.Popen object at 0x7ff1bf933d30>
>>> Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
KeyboardInterrupt
>>> 
KeyboardInterrupt

你可能会注意到启动了一个卡住的python解释器,这个:

>>> import subprocess
>>> subprocess.Popen(['python', 'whatever'])
<subprocess.Popen object at 0x7f14e1446cf8>
>>> python: can't open file 'whatever': [Errno 2] No such file or directory

尝试执行whatever

此外,您应该考虑使用communicate方法,而不是直接读取/写入stdin / stdout

答案 2 :(得分:0)

我知道这有点晚了,但是我希望这对现在有类似问题的人有所帮助。

要将输入从一个python文件发送到另一个(python版本3.7),我使用了三个文件。

  1. 用于运行子流程的文件
  2. 输出文件(非常简单)
  3. 需要输入的文件

这三个文件的顺序与上面相同。

您不需要打印输出,但是我将在文件示例下面包含终端输出。 子流程文件:

from subprocess import Popen,PIPE

p1 = Popen(["python","output_file.py"], stdout=PIPE)
p2 = Popen(["python", "input_file.py"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()

output = p2.communicate()[0]

print(output)

输出文件非常简单,可能有一种解决方法。不过,这是我的版本:

print(1)
print(2)
print('My String')

输入文件要求对数字进行类型转换。

i = input('Enter a number: ')
j = input('Enter another: ')
k = int(i) + int(j)
print(k)
l = input('Tell me something. ')
print(l)

这是终端输出:

b'Enter a number: Enter another: 3\r\nTell me something. My String!\r\n'