/ Função de retorno de chamada para processar saída - python, subprocesso, comunicação, arquivos temporários

Função de retorno de chamada para processar saída - python, subprocesso, comunicação, arquivos temporários

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 № 1

Na 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()