Como capturar a saída do interpretador Python e/ou CMD.EXE de um script Python?

StackOverflow https://stackoverflow.com/questions/24931

  •  09-06-2019
  •  | 
  •  

Pergunta

  1. É possível capturar a saída do interpretador Python a partir de um script Python?
  2. É possível capturar a saída do Windows CMD a partir de um script Python?

Em caso afirmativo, em qual(is) biblioteca(s) devo procurar?

Foi útil?

Solução

Se você está falando sobre o interpretador python ou CMD.exe que é o 'pai' do seu script, então não, não é possível.Em todo sistema tipo POSIX (agora você está executando o Windows, ao que parece, e isso pode ter alguma peculiaridade que não conheço, YMMV) cada processo tem três fluxos, entrada padrão, saída padrão e erro padrão.Por padrão (ao executar em um console), eles são direcionados para o console, mas o redirecionamento é possível usando a notação de pipe:

python script_a.py | python script_b.py

Isso vincula o fluxo de saída padrão do script a ao fluxo de entrada padrão do script B.O erro padrão ainda vai para o console neste exemplo.Veja o artigo sobre fluxos padrão na Wikipédia.

Se você está falando sobre um processo filho, você pode iniciá-lo a partir do python assim (stdin também é uma opção se você deseja comunicação bidirecional):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

Veja o Python subprocesso módulo para obter informações sobre o gerenciamento do processo.Para comunicação, os pipes process.stdin e process.stdout são considerados padrão objetos de arquivo.

Para uso com tubos, leitura da entrada padrão como Lassevk sugeri que você fizesse algo assim:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin e sys.stdout são objetos de arquivo padrão conforme observado acima, definidos no sistema módulo.Você também pode querer dar uma olhada no tubos módulo.

Ler dados com readline() como no meu exemplo é uma maneira bastante ingênua de obter dados.Se a saída não for orientada a linhas ou indeterminística, você provavelmente desejará examinar votação que infelizmente não funciona no Windows, mas tenho certeza de que existe alguma alternativa por aí.

Outras dicas

Acho que posso indicar uma boa resposta para a primeira parte da sua pergunta.

1.É possível capturar a saída da Python Interpreter de um script python?

A resposta é "sim", e pessoalmente gosto do seguinte retirado dos exemplos no PEP 343 – A declaração “com” documento.

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

E usado assim:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

Um aspecto interessante disso é que ele pode ser aplicado seletivamente em apenas uma parte da execução de um script, em vez de toda a sua extensão, e permanece em vigor mesmo quando exceções não tratadas são geradas dentro de seu contexto.Se você reabrir o arquivo no modo anexado após seu primeiro uso, poderá acumular os resultados em um único arquivo:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

É claro que o acima exposto também poderia ser estendido para redirecionar sys.stderr para o mesmo ou outro arquivo.Veja também isso responder para uma pergunta relacionada.

Na verdade, você definitivamente pode, e é lindo, feio e louco ao mesmo tempo!

Você pode substituir sys.stdout e sys.stderr por objetos StringIO que coletam a saída.

Aqui está um exemplo, salve-o como evil.py:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

Ao executar este programa, você verá que:

  • nada foi para stdout (onde print geralmente é impresso)
  • a primeira string gravada em stderr é aquela que começa com 'It'
  • as próximas duas linhas são aquelas que foram coletadas no objeto StringIO

Substituir sys.stdout/err dessa forma é uma aplicação chamada monkeypatching.As opiniões podem variar se isso é 'suportado' ou não, e é definitivamente um hack feio, mas me salvou ao tentar envolver coisas externas uma ou duas vezes.

Testado em Linux, não em Windows, mas deve funcionar igualmente bem.Deixe-me saber se funciona no Windows!

Você quer subprocesso.Veja especificamente Popen em 17.1.1 e comunique-se em 17.1.2.

Em que contexto você está perguntando?

Você está tentando capturar a saída de um programa iniciado na linha de comando?

se sim, então é assim que executá-lo:

somescript.py | your-capture-program-here

e para ler a saída, basta ler a entrada padrão.

Se, por outro lado, você estiver executando esse script ou cmd.exe ou similar de dentro do seu programa e quiser esperar até que o script/programa termine e capturar toda a sua saída, então você precisa olhar para a biblioteca chamadas que você usa para iniciar esse programa externo, provavelmente existe uma maneira de solicitar que você leia a saída e aguarde a conclusão.

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