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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top