Entrada / saída interativa usando python
Eu tenho um programa que interage com o usuário (age como um shell), e eu quero executá-lo usando o módulo subprocess python interativamente. Isso significa que eu quero a possibilidade de escrever para stdin e obter imediatamente a saída do stdout. Eu tentei muitas soluções oferecidas aqui, mas nenhuma delas parece funcionar para as minhas necessidades.
O código que eu escrevi baseado emExecutando um comando interativo de dentro do 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)
O problema é que a fila permanece vazia, como se não houvesse saída. Só se eu escrever para stdin toda a entrada que o programa precisa executar e terminar, então eu recebo a saída (que não é o que eu quero). Por exemplo, se eu fizer algo como:
p.stdin.write("1\n5\n")
errors = getOutput(errQueue)
output = getOutput(outQueue)
Existe alguma maneira de fazer o que eu quero fazer?
EDITAR: O script será executado em uma máquina Linux. Eu mudei meu script e deletei o universal_newlines = True + definir o bufsize para 1 e stdin liberado imediatamente após wrtie. Ainda não recebo saída.
Segunda tentativa: Eu tentei esta solução e funciona para mim:
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()