重定向FD后如何写入stdout

时间:2018-08-08 12:58:44

标签: python stdout

请在下面查看此python代码。

so = open('/tmp/test.log', 'a+')
os.dup2(so.fileno(), sys.stdout.fileno())

执行完这段代码后,我仍然希望可以在标准stdout上打印一些内容。


我已经尝试过:

print('Foo\n', file=sys.__stdout__)

根据documentation,这可能是一种解决方法。

sys.__stdin__
sys.__stdout__
sys.__stderr__
  

这些对象包含stdin,stderr和stdout的原始值   在程序开始时。在定稿过程中使用它们,并且   不管是否使用   sys.std *对象已被重定向。

但事实并非如此。它仍然记录到我的 test.log 文件中。

Python版本: 3.4.8

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:7)

sys.__stdout__不起作用的原因是因为您用os.dup2()替换了原始stdout的文件描述符,所以基于它的 any Python文件对象将打印到新打开的文件。实际上,当您执行dup2时,旧的标准输出实际上已关闭,因此无法恢复。

如果您想拥有所有使用sys.stdout打印到/tmp/test.log的Python代码,请打开一个新文件并将其分配给sys.stdout

sys.stdout = open('/tmp/test.log', 'a+')

原始sys.stdout将以sys.__stdout__的形式提供。

如果您还想将直接写到sys.stdout.fileno()的所有代码重定向,包括以os.system()subprocess.call()开头的子进程,同时保持对原始stdout的访问权限,变得更加复杂:您首先需要dup()标准输出并保存,然后使用dup2()调用来替换FD 1:

saved_stdout_fd = os.dup(sys.stdout.fileno())
saved_stdout = os.fdopen(saved_stdout_fd,'w')
so = open('/tmp/test.log', 'a+')
os.dup2(so.fileno(), sys.stdout.fileno())

现在sys.stdout进入您的/tmp/test.logsaved_stdout将写入原始标准输出。