Piping output of subprocess.Popen to files

前端 未结 3 1768
一向
一向 2020-12-02 17:00

I need to launch a number of long-running processes with subprocess.Popen, and would like to have the stdout and stderr from each auto

3条回答
  •  渐次进展
    2020-12-02 17:24

    I am simultaneously running two subprocesses, and saving the output from both into a single log file. I have also built in a timeout to handle hung subprocesses. When the output gets too big, the timeout always triggers, and none of the stdout from either subprocess gets saved to the log file. The answer posed by Alex above does not solve it.

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

提交回复
热议问题