记录进程的标准输入和标准输出

1 投票
1 回答
2289 浏览
提问于 2025-04-17 13:02

我想用 subprocess.Popen() 来运行一个进程,并通过 Python 的命令行和它进行交流,就像 subprocess.Popen 通常的用法那样。除此之外,我还想把输入和输出的内容记录到一个日志文件里。

我该怎么做呢?

1 个回答

1

假设“discursively”是指冗长的意思,而“rambling”则意味着所有内容都在同一个文件里,那么下面的代码片段就是你需要的。

冗长的日志记录,区分来源和交互

重写它的 communicate 方法,类似于这个问题 这里 的做法。

import subprocess

def logcommunicate(self, s):
    self.logfilehandle.write("Input "+s)
    std = self.oldcommunicate(s)

    self.logfilehandle.write("Output "+std[0])
    return std

subprocess.Popen.oldcommunicate = subprocess.Popen.communicate
subprocess.Popen.communicate = logcommunicate
logfh = open("/tmp/communicate.log", "a")

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.logfilehandle = logfh

result = proc.communicate("hello there\n")
print result 

冗长的日志记录,区分来源

首先使用 StringIO 而不是文件,然后创建一个 StringIO 的子类,重写它的 write 方法,添加时间戳和来源。接着写一个自定义的比较函数,根据时间戳和来源进行排序,先按时间戳,再按来源,输入在前,输出在后。

 with open("file.log","wb") as in logfile:
 out = MyOutPutStringIO.StringIO() 
 in = MyInputStringIO.StringIO()
 subprocess.Popen(cmd, shell=True, universal_newlines = True, stdin=in, stdout=out)

 #Then after you are done
 linestotal = []
 for line in in.readlines():
     linestotal.append(line)
 for line in out.readlines():
     linestotal.append(line)

 linestotal.sort(customsortbasedontimestampandinput)

 for line in linestotal.readlines():
    logwrite.write(line)

冗长的日志记录

 with open("file.log","wb") as in logfile:
 subprocess.Popen(cmd, shell=True, universal_newlines = True, stdin=logfile, stdout=logfile)

下面展示的是相反的情况。

简洁的日志记录

 with open("stdout.txt","wb") as out:
 with open("stderr.txt","wb") as err:
 with open("stdin.txt","wb") as in:
 subprocess.Popen(cmd, shell=True, universal_newlines = True, stdin=in,stdout=out,stderr=err)

撰写回答