编辑:由于看起来要么没有解决方案,要么我正在做一些如此非标准的事情以至于没有人知道 - 我将修订我的问题,还要问:在 Python 应用程序进行大量系统调用时,实现记录日志的最佳方法是什么?
我的应用程序有两种模式。在交互模式下,我希望所有输出都能显示在屏幕上并写入日志文件,包括任何系统调用的输出。在守护进程模式下,所有输出都写入日志中。使用 os.dup2()
守护进程模式非常好用。但是在交互模式下,我找不到“tee”所有输出到日志的方法,而无需修改每个系统调用。
换句话说,我想要一个类似命令行工具 'tee' 的功能,用于捕获 Python 应用程序生成的所有输出,包括系统调用输出。
澄清一下:
为了重定向所有输出,我做了以下操作,效果非常好:
# open our log file
so = se = open("%s.log" % self.name, 'w', 0)
# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
这样做的好处是不需要在代码中特别指定打印调用。此外,代码还运行了一些shell命令,因此不必单独处理它们的输出也很方便。
简单来说,我想做同样的事情,只是要“复制”而不是重定向。
一开始我认为只需简单地反转dup2
就可以了,为什么不行?以下是我的测试:
import os, sys
### my broken solution:
so = se = open("a.log", 'w', 0)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
os.dup2(sys.stdout.fileno(), so.fileno())
os.dup2(sys.stderr.fileno(), se.fileno())
###
print("foo bar")
os.spawnve("P_WAIT", "/bin/ls", ["/bin/ls"], {})
os.execve("/bin/ls", ["/bin/ls"], os.environ)
文件"a.log"应该与屏幕上显示的内容完全相同。