sortie de tuyauterie du sous-processus.Popen aux fichiers
J'ai besoin de lancer un certain nombre de processus de longue durée avec subprocess.Popen
, et je voudrais que les stdout
et stderr
de chacun soient automatiquement redirigés vers des fichiers journaux séparés. Chaque processus s'exécutera simultanément pendant plusieurs minutes, et je veux deux fichiers journaux (stdout
et stderr
) par processus à écrire pendant l'exécution des processus.
Dois-je l'appelle sans cesse p.communicate()
sur chaque processus en boucle afin de mettre à jour chaque fichier journal, ou est-il un moyen d'invoquer l'original Popen
commande alors que stdout
et stderr
sont automatiquement diffusés pour ouvrir les poignées de fichiers?
3 réponses
Par les documents ,
Stdin, stdout et stderr spécifient entrée standard des programmes exécutés, sortie standard et erreur standard poignées de fichiers, respectivement. Valide les valeurs sont PIPE, un fichier existant descripteur (un entier positif), une objet fichier existant, et aucun.
Il suffit donc de passer les objets open-for-writing file en tant qu'arguments nommés stdout=
et stderr=
et vous devriez aller bien!
, Vous pouvez passer stdout
et stderr
en tant que paramètres de Popen()
subprocess.Popen(self, args, bufsize=0, executable=None, stdin=None, stdout=None,
stderr=None, preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False, startupinfo=None,
creationflags=0)
Par exemple
>>> import subprocess
>>> with open("stdout.txt","wb") as out, open("stderr.txt","wb") as err:
... subprocess.Popen("ls",stdout=out,stderr=err)
...
<subprocess.Popen object at 0xa3519ec>
>>>
J'exécute simultanément deux sous-processus et enregistre la sortie des deux dans un seul fichier journal. J'ai également intégré un délai d'attente pour gérer les sous-processus suspendus. Lorsque la sortie devient trop grande, le délai d'attente se déclenche toujours, et aucun des stdout de l'un ou l'autre sous-processus n'est enregistré dans le fichier journal. La réponse posée par Alex ci-dessus ne le résout pas.
# Currently open log file.
log = None
# If we send stdout to subprocess.PIPE, the tests with lots of output fill up the pipe and
# make the script hang. So, write the subprocess's stdout directly to the log file.
def run(cmd, logfile):
#print os.getcwd()
#print ("Running test: %s" % cmd)
global log
p = subprocess.Popen(cmd, shell=True, universal_newlines = True, stderr=subprocess.STDOUT, stdout=logfile)
log = logfile
return p
# To make a subprocess capable of timing out
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
log.flush()
raise Alarm
####
## This function runs a given command with the given flags, and records the
## results in a log file.
####
def runTest(cmd_path, flags, name):
log = open(name, 'w')
print >> log, "header"
log.flush()
cmd1_ret = run(cmd_path + "command1 " + flags, log)
log.flush()
cmd2_ret = run(cmd_path + "command2", log)
#log.flush()
sys.stdout.flush()
start_timer = time.time() # time how long this took to finish
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(5) #seconds
try:
cmd1_ret.communicate()
except Alarm:
print "myScript.py: Oops, taking too long!"
kill_string = ("kill -9 %d" % cmd1_ret.pid)
os.system(kill_string)
kill_string = ("kill -9 %d" % cmd2_ret.pid)
os.system(kill_string)
#sys.exit()
end_timer = time.time()
print >> log, "closing message"
log.close()