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?

37
demandé sur Dawid Ferenczy 2010-02-25 06:08:15

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!

34
répondu Alex Martelli 2010-02-25 03:18:00

, 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>
>>> 
60
répondu John La Rooy 2013-08-25 21:31:27

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()
2
répondu jasper77 2010-09-22 21:15:21