¿Cómo capturar el intérprete de Python y / o la salida de CMD.EXE de un script de Python?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

  1. ¿Es posible capturar la salida del intérprete de Python desde un script de Python?
  2. ¿Es posible capturar la salida de Windows CMD desde un script de Python?

Si es así, ¿qué bibliotecas (s) debo ver?

¿Fue útil?

Solución

Si está hablando del intérprete de python o CMD.exe que es el "padre" de su script, entonces no, no es posible. En cada sistema similar a POSIX (ahora está ejecutando Windows, parece, y eso podría tener alguna peculiaridad que no conozco, YMMV) cada proceso tiene tres flujos, entrada estándar, salida estándar y error estándar. Bu predeterminado (cuando se ejecuta en una consola) estos se dirigen a la consola, pero la redirección es posible utilizando la notación de canalización:

python script_a.py | python script_b.py

Esto vincula el flujo de salida estándar del script a al flujo de entrada estándar del script B. En este ejemplo, el error estándar aún va a la consola. Consulte el artículo en transmisiones estándar en Wikipedia.

Si estás hablando de un proceso secundario, puedes iniciarlo desde python así (stdin también es una opción si quieres una comunicación bidireccional):

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

Consulte el módulo subproceso de Python para obtener información sobre cómo gestionar el proceso. Para la comunicación, las canalizaciones process.stdin y process.stdout se consideran estándar objetos de archivo .

Para usar con tuberías, leer desde la entrada estándar como lassevk sugirió que harías algo como esto:

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

sys.stdin y sys.stdout son objetos de archivo estándar como se indicó anteriormente, definidos en módulo sys . Es posible que también desee ver el módulo canalizaciones .

Sin embargo, leer datos con readline () como en mi ejemplo es una forma bastante ingenua de obtener datos. Si la salida no está orientada a la línea o es indeterminista, probablemente quiera ver sondeo que desafortunadamente no funciona en Windows, pero estoy seguro de que hay alguna alternativa por ahí.

Otros consejos

Creo que puedo señalarle una buena respuesta para la primera parte de su pregunta.

  

1. & nbsp; & nbsp; ¿Es posible capturar la salida del intérprete de Python desde un Python?   script?

La respuesta es " " ;, y personalmente me gusta lo siguiente, que se desprende de los ejemplos en PEP 343 - El " con " Documento de declaración .

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

Y se usa así:

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

Un buen aspecto es que se puede aplicar selectivamente alrededor de solo una parte de la ejecución de un script, en lugar de su extensión completa, y permanece vigente incluso cuando se generan excepciones no controladas dentro de su contexto. Si vuelve a abrir el archivo en modo agregado después de su primer uso, puede acumular los resultados en un solo archivo:

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"

Por supuesto, lo anterior también podría extenderse para redirigir también sys.stderr al mismo u otro archivo. Consulte también esta respuesta a una pregunta relacionada.

En realidad, definitivamente puedes, ¡y es hermoso, feo y loco al mismo tiempo!

Puede reemplazar sys.stdout y sys.stderr con objetos StringIO que recopilan la salida.

Aquí hay un ejemplo, guárdelo 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())

Cuando ejecute este programa, verá que:

  • nada fue a la salida estándar (donde la impresión se imprime generalmente a)
  • la primera cadena que se escribe en stderr es la que comienza con 'It'
  • las siguientes dos líneas son las que se recolectaron en el objeto StringIO

Reemplazar sys.stdout / err como esta es una aplicación de lo que se llama monkeypatching. Las opiniones pueden variar si esto es "compatible" o no, y definitivamente es un truco feo, pero me ha salvado el problema cuando trato de envolver cosas externas una o dos veces.

Probado en Linux, no en Windows, pero debería funcionar igual de bien. ¡Avísame si funciona en Windows!

Desea subprocess . Mire específicamente a Popen en 17.1.1 y comuníquese en 17.1.2.

¿En qué contexto estás preguntando?

¿Estás tratando de capturar la salida de un programa que inicias en la línea de comando?

si es así, entonces así es como ejecutarlo:

somescript.py | your-capture-program-here

y para leer la salida, solo lea desde la entrada estándar.

Si, por otro lado, está ejecutando ese script o cmd.exe o similar desde su programa, y ??desea esperar hasta que el script / programa haya finalizado, y capturar toda su salida, entonces debe mirar En la biblioteca de llamadas que usa para iniciar ese programa externo, lo más probable es que haya una forma de pedirle que le brinde alguna forma de leer el resultado y esperar a que se complete.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top