У меня есть программа, которая взаимодействует с пользователем (действует как оболочка), и я хочу запустить ее с помощью модуля подпроцесса python в интерактивном режиме. Это означает, что я хочу возможность написать stdin и сразу получить вывод из stdout. Я пробовал много решений, предлагаемых здесь, но никто из них, похоже, не работает для моих нужд.
Код, который я написал на основе Запуск интерактивной команды изнутри python
import Queue
import threading
import subprocess
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
def getOutput(outQueue):
outStr = ''
try:
while True: #Adds output from the Queue until it is empty
outStr+=outQueue.get_nowait()
except Queue.Empty:
return outStr
p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize = 1)
#p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)
outQueue = Queue()
errQueue = Queue()
outThread = Thread(target=enqueue_output, args=(p.stdout, outQueue))
errThread = Thread(target=enqueue_output, args=(p.stderr, errQueue))
outThread.daemon = True
errThread.daemon = True
outThread.start()
errThread.start()
p.stdin.write("1\n")
p.stdin.flush()
errors = getOutput(errQueue)
output = getOutput(outQueue)
p.stdin.write("5\n")
p.stdin.flush()
erros = getOutput(errQueue)
output = getOutput(outQueue)
Проблема в том, что очередь остается пустой, как будто нет выхода. Только если я напишу stdin все входные данные, которые программа должна выполнить и завершить, тогда я получаю вывод (что не то, что я хочу). Например, если я делаю что-то вроде:
p.stdin.write("1\n5\n")
errors = getOutput(errQueue)
output = getOutput(outQueue)
Есть ли способ сделать то, что я хочу сделать?
EDIT: script будет запущен на машине Linux. Я изменил свой script и удалил universal_newlines = True + установил bufsize в 1 и сбросил stdin сразу после wrtie. Тем не менее я не получаю выход.
Вторая попытка: Я пробовал это решение, и оно работает для меня:
from subprocess import Popen, PIPE
fw = open("tmpout", "wb")
fr = open("tmpout", "r")
p = Popen("./a.out", stdin = PIPE, stdout = fw, stderr = fw, bufsize = 1)
p.stdin.write("1\n")
out = fr.read()
p.stdin.write("5\n")
out = fr.read()
fw.close()
fr.close()