编辑: 由于看起来要么没有解决方案,要么我在做一些没有人知道的非标准的事情——我将修改我的问题,还要问: 当一个 python 应用程序进行大量的系统调用时,什么是完成日志记录的最佳方法?
我的应用程序有两种模式。在交互模式下,我希望所有输出都转到屏幕和日志文件,包括任何系统调用的输出。在守护进程模式下,所有输出都会转到日志。守护进程模式使用 os.dup2()
工作得很好。如果不修改每个系统调用,我无法找到一种方法将所有输出“ T”到交互模式的日志中。
换句话说,我需要命令行‘ 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())
这样做的好处是不需要来自代码其余部分的特殊 print 调用。代码还运行一些 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”应该与屏幕上显示的内容相同。