Recentemente eu tenho brincado com Popen
. Eu criei um processo em um plano de fundo que grava a saída para um TemporaryFile
:
f = tempfile.TemporaryFile()
p = subprocess.Popen(["gatttool"], stdin = subprocess.PIPE, stdout = f)
Agora funciona de uma forma que eu envio um comando para o processo via stdin
e leia um pouco depois o arquivo temporário. E não bloqueia, então eu posso executar outras tarefas.
O problema é que gatttool
às vezes gera alguma saída por si mesmo (por exemplo, notificações). E eu estou procurando uma maneira de ler esta saída sem bloquear o TemporaryFile
.
Minha pergunta:
1) É seguro ler a saída de um TemporaryFile
(50 linhas) e espero que subprocess
graciosamente espera por mim para ler esses dados ou vai terminar?
2) Existe uma maneira elegante de criar uma função de retorno de chamada que será chamada em todos os eventos em TemporaryFile
(em vez de ter um thread que será executado a cada segundo e ler os dados)?
Respostas:
0 para resposta № 1Na verdade, a resolução é muito simples. Criar uma pipe
, use o gatttool
saída como a entrada. A saída desse tubo vai para um thread
, que lê essa saída, linha por linha e cada uma dessa linha é analisada. Verificado e funciona. Por favor, bloqueie esta questão.
# Create a pipe. "gatt_in" ins where the "gatttool" will be dumping it"s output.
# We read that output from the other end of pipe, "gatt_out"
gatt_out, gatt_in = os.pipe()
gatt_process = subprocess.Popen(["gatttool", "your parametres"], stdin = subprocess.PIPE,
stdout = gatt_in)
Agora toda vez que eu quero enviar um comando para gatttool
Eu faço isso:
gatt_process.stdin.write("Some commandsn")
O resultado deste comando aparecerá em gatt_out
. No meu caso, isso é tratado em outro thread.
0 para resposta № 2
Para fornecer entrada / obter saída de um processo filho, você pode usar subprocess.PIPE
:
from subprocess import Popen, PIPE
p = Popen(["gatttool", "arg 1", "arg 2"], stdin=PIPE, stdout=PIPE, bufsize=1)
# provide input
p.stdin.write(b"input data")
p.stdin.close()
# read output incrementally (in "real-time")
for line in iter(p.stdout.readline, b""):
print line,
p.stdout.close()
p.wait()