如何在Python中将标准输出重定向到任意文件?

When a long-running Python script (e.g, web application) is started from within the ssh session and backgounded, and the ssh session is closed, the application will raise IOError and fail the moment it tries to write to stdout. I needed to find a way to make the application and modules output to a file rather than stdout to prevent failure due to IOError. Currently, I employ nohup to redirect output to a file, and that gets the job done, but I was wondering if there was a way to do it without using nohup, out of curiosity.

我已经试过了。Stdout = open('somefile', 'w'),但这似乎并没有阻止一些外部模块仍然输出到终端(或者sys. exe)。Stdout =…Line根本没有开火)。我知道它应该在我测试过的更简单的脚本上工作,但我还没有时间在web应用程序上进行测试。


当前回答

我知道这个问题已经得到了回答(使用python abc.py > output.log 2>&1),但我仍然不得不说:

在编写程序时,不要写入标准输出。总是使用日志来输出您想要的任何东西。这在以后你想重定向,过滤,旋转输出文件的时候会给你很大的自由。

其他回答

引用自PEP 343 -“with”语句(添加了import语句):

临时重定向标准输出:

import sys
from contextlib import contextmanager
@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

用途如下:

with open(filename, "w") as f:
    with stdout_redirected(f):
        print "Hello world"

当然,这不是线程安全的,但手动执行相同的操作也不是。在单线程程序(例如脚本)中,这是一种流行的做事方式。

其他答案不包括您希望分叉进程共享您的新标准输出的情况。

做那件事:

from os import open, close, dup, O_WRONLY

old = dup(1)
close(1)
open("file", O_WRONLY) # should open on 1

..... do stuff and then restore

close(1)
dup(old) # should dup to 1
close(old) # get rid of left overs

还有其他使用上下文的版本,但没有这么简单。实际上,我只是在谷歌上仔细检查了一下,并惊讶地没有看到它,所以对于其他人来说,寻找一个快速的解决方案是安全的,只针对上下文块中的代码,这里是:

import sys
with open('test_file', 'w') as sys.stdout:
    print('Testing 1 2 3')

测试如下:

$ cat redirect_stdout.py 导入系统 将open('test_file', 'w')作为sys.stdout: 打印('测试1 2 3') $ python redirect_stdout.py $ cat test_file 测试1 2 3

我知道这个问题已经得到了回答(使用python abc.py > output.log 2>&1),但我仍然不得不说:

在编写程序时,不要写入标准输出。总是使用日志来输出您想要的任何东西。这在以后你想重定向,过滤,旋转输出文件的时候会给你很大的自由。

用其他语言(例如C)编写的程序必须使用特殊的魔法(称为双分叉)来明确地与终端分离(并防止僵尸进程)。所以,我认为最好的解决办法是模仿他们。

重新执行程序的一个好处是,你可以在命令行上选择重定向,例如/usr/bin/python mycoolscript.py 2>&1 1>/dev/null

查看这篇文章了解更多信息:在创建守护进程时执行双fork的原因是什么?