Python - captura stdout Popen e exibir no console?
Pergunta
Eu quero stdout captura de um processo de execução longa-ish iniciado através subprocess.Popen(...)
então estou usando stdout=PIPE
como arg.
No entanto, porque é um processo de longa duração Eu também quero enviar a saída para o console (como se eu não tivesse canalizado lo) para dar ao usuário do script uma idéia que ele ainda está funcionando.
É este for possível?
Felicidades.
Solução
Você pode simplesmente print
-lo como você lê-lo a partir do tubo?
Outras dicas
O tamponamento seu sub-processo de longa duração é, provavelmente, a realização vai fazer a sua jerky saída do console e muito ruim UX. Eu sugiro que você considere em vez de usar pexpect (ou, no Windows, wexpect ) para derrotar tais buffer e obter alisar, saída regulares do sub-processo. Por exemplo (em praticamente qualquer sistema unix-y, depois de instalar pexpect):
>>> import pexpect
>>> child = pexpect.spawn('/bin/bash -c "echo ba; sleep 1; echo bu"', logfile=sys.stdout); x=child.expect(pexpect.EOF); child.close()
ba
bu
>>> child.before
'ba\r\nbu\r\n'
O ba e bu virá com o momento adequado (cerca de um segundo entre eles). Observe a saída não está sujeito ao processamento do terminal normal, de modo que os retornos de carro são deixados lá - você vai precisar para pós-processar a cadeia se (apenas um .replace
simples -!) Se você precisa \n
como end-of-line marcadores (a falta de processamento é importante apenas no caso do sub-processo é a gravação de dados binários para a sua stdout - isso garante todos dos dados deixados intactos -!).
S. de Lott comentário aponta para Obtendo saída em tempo real usando subprocesso e Real-time interceptando de stdout de outro processo em Python
Estou curioso que a resposta de Alex aqui é diferente de sua resposta 1.085.071. Minhas experiências pouco simples com as respostas nas duas outras questões referenciadas tem dado bons resultados ...
Eu fui e olhou para wexpect conforme a resposta de Alex acima, mas eu tenho que dizer ler os comentários no código que não foi deixado um sentimento muito bom sobre a usá-lo.
Eu acho que a meta-questão aqui é quando vai pexpect / wexpect ser uma das baterias incluídas?
Inspirado pela pty.openpty () em algum lugar sugestão acima, testado em python2.6, linux. Publicando desde que levou um tempo para fazer este trabalho corretamente, w / o buffer ...
def call_and_peek_output(cmd, shell=False):
import pty, subprocess
master, slave = pty.openpty()
p = subprocess.Popen(cmd, shell=shell, stdin=None, stdout=slave, close_fds=True)
os.close(slave)
line = ""
while True:
try:
ch = os.read(master, 1)
except OSError:
# We get this exception when the spawn process closes all references to the
# pty descriptor which we passed him to use for stdout
# (typically when it and its childs exit)
break
line += ch
sys.stdout.write(ch)
if ch == '\n':
yield line
line = ""
if line:
yield line
ret = p.wait()
if ret:
raise subprocess.CalledProcessError(ret, cmd)
for l in call_and_peek_output("ls /", shell=True):
pass
Como alternativa, você pode enviar o seu processo em T e capturar apenas um dos córregos.
Algo ao longo das linhas de sh -c 'process interesting stuff' | tee /dev/stderr
.
Claro, isso só funciona em sistemas Unix-like.