首页 > 解决方案 > 重定向 FD 后如何写入标准输出

问题描述

请看下面的这个python代码。

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

执行那段代码后,我希望仍然可以在标准标准输出上打印一些东西。


我已经尝试过:

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

根据文档可能是一种方法。

sys.__stdin__
sys.__stdout__
sys.__stderr__

这些对象包含程序开始时 stdin、stderr 和 stdout 的原始值。它们在最终确定期间使用,并且无论 sys.std* 对象是否已被重定向,都可以用于打印到实际的标准流。

但情况并非如此。它仍在记录到我的test.log文件。

Python版本:3.4.8

任何帮助将不胜感激。

标签: pythonstdout

解决方案


原因sys.__stdout__不起作用是因为您将原始标准输出的文件描述符替换为os.dup2(),因此任何基于它的 Python 文件对象都会打印到新打开的文件中。当你这样做时,旧的标准输出实际上会被关闭dup2,所以没有恢复它。

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

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

原件sys.stdout仍可作为sys.__stdout__.

如果您还想重定向任何直接写入 sys.stdout.fileno() 的代码,包括您以os.system()or开头的子进程subprocess.call(),同时保持对原始标准输出的访问,事情变得更加复杂:您需要先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.log并将saved_stdout写入原始标准输出。


推荐阅读