example español check_output python linux subprocess stdout python-2.4

python - español - Guardando stdout de subprocess.Popen en el archivo, además de escribir más cosas en el archivo



subprocess.check_output example python (4)

Estoy escribiendo una secuencia de comandos de Python que utiliza subprocess.Popen para ejecutar dos programas (a partir de código C compilado), cada uno de los cuales produce una salida estándar. El script obtiene esa salida y la guarda en un archivo. Debido a que la salida es a veces lo suficientemente grande como para abrumar a subprocess.PIPE, lo que provoca que el script se bloquee, envío la salida estándar directamente al archivo de registro. Quiero que mi script escriba algo al principio y al final del archivo, y entre los dos subprocesos. Llamadas abiertas. Sin embargo, cuando miro mi archivo de registro, todo lo que escribí en el archivo de registro desde la secuencia de comandos está todo junto en la parte superior del archivo, seguido de toda la salida estándar ejecutable. ¿Cómo puedo intercalar mi texto agregado al archivo?

def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) return p def runTest(path, flags, name): log = open(name, "w") print >> log, "Calling executable A" a_ret = run(path + "executable_a_name" + flags, log) print >> log, "Calling executable B" b_ret = run(path + "executable_b_name" + flags, log) print >> log, "More stuff" log.close()

El archivo de registro tiene: Llamando al ejecutable A Llamando al ejecutable B Más cosas [... stdout de ambos ejecutables ...]

¿Hay alguna manera de poder vaciar la salida estándar de A al registro después de llamar a Popen, por ejemplo? Una cosa más que podría ser relevante: el ejecutable A comienza, luego se inclina sobre B, y después de que B imprime y termina, A luego imprime más y termina.

Estoy usando Python 2.4 en RHE Linux.


Debe esperar hasta que finalice el proceso antes de continuar. También he convertido el código para usar un administrador de contexto, que es más limpio.

def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) p.wait() return p def runTest(path, flags, name): with open(name, "w") as log: print >> log, "Calling executable A" a_ret = run(path + "executable_a_name" + flags, log) print >> log, "Calling executable B" b_ret = run(path + "executable_b_name" + flags, log) print >> log, "More stuff"


Puede llamar a .wait () en cada objeto Popen para asegurarse de que está terminado y luego llamar a log.flush (). Tal vez algo como esto:

def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) ret_code = p.wait() logfile.flush() return ret_code

Si necesita interactuar con el objeto Popen en su función externa, podría mover la llamada .wait () a ese lugar.


Según tengo entendido, A programa espera que B haga su trabajo y A sale solo después de que B sale.

Si B puede comenzar sin que A ejecute, puede iniciar los procesos en orden inverso:

from os.path import join as pjoin from subprocess import Popen def run_async(cmd, logfile): print >>log, "calling", cmd p = Popen(cmd, stdout=logfile) print >>log, "started", cmd return p def runTest(path, flags, name): log = open(name, "w", 1) # line-buffered print >>log, ''calling both processes'' pb = run_async([pjoin(path, "executable_b_name")] + flags.split(), log) pa = run_async([pjoin(path, "executable_a_name")] + flags.split(), log) print >>log, ''started both processes'' pb.wait() print >>log, ''process B ended'' pa.wait() print >>log, ''process A ended'' log.close()

Nota: llamar a log.flush() en los procesos principales no tiene ningún efecto en los buffers de archivos en los procesos secundarios.

Si los procesos secundarios utilizan el almacenamiento en búfer para stdout, entonces podría intentar forzarlos a vaciarse antes utilizando pexpect, pty o stdbuf (se supone que los procesos usan el almacenamiento en línea si se ejecutan de forma interactiva o usan la biblioteca C stdio para E / S) .


Yo digo que sea muy simple. Lógica básica del pseudo código:

write your start messages to logA execute A with output to logA write your in-between messages to logB execute B with output to logB write your final messages to logB when A & B finish, write content of logB to the end of logA delete logB