¿Cómo se imprime salidas de llamadas a subprocess.Popen (...) en un bucle?
-
23-08-2019 - |
Pregunta
escribí un script para ejecutar un programa de línea de comandos con diferentes argumentos de entrada y tomar una cierta línea de la salida. Tengo el siguiente que se ejecuta en un bucle:
p1 = subprocess.Popen(["program", args], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(["grep", phrase], stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p = str(p2.stdout.readlines())
print 'p is ', p
Uno de los problemas es que no sólo se emite después de que el bucle se termina de ejecutarse. Quiero imprimir algo cada vez que un proceso ha terminado. ¿Cómo puedo hacer eso?
Además, quiero tener la opción de visualizar la salida de P1. Pero no puedo agarrar con p1.stdout.readlines () sin romper p2. ¿Cómo puedo hacer esto?
Yo estaba pensando que yo no podía hacer la llamada a grep, almacenar la salida de p1 y la búsqueda de la frase, pero hay una gran cantidad de la producción, por lo que de esta manera parece bastante ineficiente.
Cualquier sugerencia sería muy apreciada. Gracias!
Solución
Aquí hay un truco rápido que trabajó para mí en Linux. Puede que funcione para usted, dependiendo de sus necesidades. Utiliza camiseta como un filtro que, si pasa a su print_all
guión, duplicará una copia adicional a / dev / tty (bueno, lo dije era un hack):
#!/usr/bin/env python
import subprocess
import sys
phrase = "bar"
if len(sys.argv) > 1 and sys.argv[1] == 'print_all':
tee_args = ['tee', '/dev/tty']
else:
tee_args = ['tee']
p1 = subprocess.Popen(["./program"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(tee_args, stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p3 = subprocess.Popen(["grep", phrase], stdin=p2.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p3.wait()
p = str(p3.stdout.readlines())
print 'p is ', p
con la siguiente como contenidos para program
:
#!/bin/sh
echo foo
echo bar
echo baz
Ejemplo de salida:
$ ./foo13.py p is ['bar\n'] $ ./foo13.py print_all foo bar baz p is ['bar\n']
Otros consejos
Trate de llamar sys.stdout.flush () después de cada sentencia print.