pipe道输出的subprocess。打开到文件

我需要使用subprocess.Popen启动一些长时间运行的进程,并希望从每个自动pipe道的stdoutstderr单独的日志文件。 每个进程将同时运行几分钟,并且我希望每个进程有两个日志文件( stdoutstderr )在进程运行时写入。

为了更新每个日志文件,是否需要在循环中的每个进程上不断调用p.communicate() ,还是有一些方法来调用原始Popen命令,以便stdoutstderr自动stream式传输以打开文件句柄?

根据文档 ,

stdin,stdout和stderr分别指定执行程序的标准input,标准输出和标准错误文件句柄。 有效值是PIPE,现有文件描述符(正整数),现有文件对象和None。

所以只需将打开的文件对象作为命名参数stdout=stderr=传递就可以了。

您可以将stdoutstderr作为parameter passing给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) 

例如

 >>> 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> >>> 

我同时运行两个subprocess,并将两者的输出保存到一个日志文件中。 我也build立了超时处理挂起的subprocess。 当输出变得太大时,超时总是触发,并且任何一个subprocess的stdout都不会被保存到日志文件中。 上面Alex提出的答案并不能解决这个问题。

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