重定向FD后如何写入stdout

Daw*_*uba 4 python stdout

请看下面的python代码.

so = open('/tmp/test.log', 'a+')
os.dup2(so.fileno(), sys.stdout.fileno())
Run Code Online (Sandbox Code Playgroud)

在执行那段代码后,我仍然希望在标准的stdout上打印一些东西.


我已经尝试过:

print('Foo\n', file=sys.__stdout__)
Run Code Online (Sandbox Code Playgroud)

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

sys.__stdin__
sys.__stdout__
sys.__stderr__
Run Code Online (Sandbox Code Playgroud)

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

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

Python版本:3.4.8

任何帮助将不胜感激.

Leo*_*o K 7

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

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

sys.stdout = open('/tmp/test.log', 'a+')
Run Code Online (Sandbox Code Playgroud)

原件sys.stdout仍然可用sys.__stdout__.

如果你想要重定向直接写入sys.stdout.fileno()的任何代码,包括你开始使用的子进程,os.system()或者subprocess.call()在保持对原始stdout的访问的同时,事情会变得更复杂:你需要先dup()stdout并保存,然后用你的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())
Run Code Online (Sandbox Code Playgroud)

现在sys.stdout去你的/tmp/test.log,并saved_stdout会写原来的标准输出.