如何在Python中重定向stderr?

Eci*_*irH 19 python redirect stderr

我想记录Python脚本的所有输出.我试过了:

import sys

log = []

class writer(object):
    def write(self, data):
        log.append(data)

sys.stdout = writer()
sys.stderr = writer()
Run Code Online (Sandbox Code Playgroud)

现在,如果我"打印'某些东西'"它就会被记录下来.但是,如果我做了一些语法错误,比如说"打印'某些东西#",它就不会被记录 - 它将进入控制台.

我如何捕获Python解释器中的错误?

我看到了一个可能的解决方案:

http://www.velocityreviews.com/forums/showpost.php?p=1868822&postcount=3

但第二个例子登录到/ dev/null - 这不是我想要的.我想将它记录到像我上面的例子或StringIO这样的列表中......

另外,我最好不要创建子进程(并在单独的线程中读取它的stdout和stderr).

Kin*_*cal 20

我有一个我为工作编写的软件,它将stderr捕获到一个文件中,如下所示:

import sys
sys.stderr = open('C:\\err.txt', 'w')
Run Code Online (Sandbox Code Playgroud)

所以这绝对是可能的.

我相信你的问题是你正在创建两个编写器实例.

也许更像是:

import sys

class writer(object):
    log = []

    def write(self, data):
        self.log.append(data)

logger = writer()
sys.stdout = logger
sys.stderr = logger
Run Code Online (Sandbox Code Playgroud)


小智 8

要从 Windows 路由输出和错误,您可以在 Python 文件外部使用以下代码:

python a.py 1> a.out 2>&1
Run Code Online (Sandbox Code Playgroud)

来源:https://support.microsoft.com/en-us/help/110930/redirecting-error-messages-from-command-prompt-stderr-stdout


Ned*_*der 6

您无法在Python代码中执行任何可以在编译相同代码期间捕获错误的操作.怎么可能呢?如果编译器无法完成编译代码,它将无法运行代码,因此您的重定向甚至尚未生效.

这就是你的(不需要的)子进程的用武之地.你可以编写重定向stdout的Python代码,然后调用Python解释器来编译其他一些代码.

  • @EthanBierlein Python确实是编译的,但是要字节码,而不是机器指令.关键是有一个编译步骤,它产生SyntaxErrors.如果发生SyntaxError,则代码将不会运行,因此您无法在代码中执行任何操作来记录语法错误. (2认同)

小智 6

我想不出一个简单的方法.python进程的标准错误生成在比python文件对象(C vs. python)更低的层次上.

您可以将python脚本包装在第二个python脚本中并使用subprocess.Popen.你也可以在一个脚本中拉出这样的魔法:

import os
import subprocess
import sys

cat = subprocess.Popen("/bin/cat", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
os.close(sys.stderr.fileno())
os.dup2(cat.stdin.fileno(), sys.stderr.fileno())
Run Code Online (Sandbox Code Playgroud)

然后使用select.poll()定期检查cat.stdout以查找输出.

是的,这似乎有效.

我预见的问题是,大多数时候,python打印到stderr的东西表明它即将退出.处理这种情况的更常用方法是通过例外.

- - - - -编辑

不知怎的,我错过了os.pipe()函数.

import os, sys
r, w = os.pipe()
os.close(sys.stderr.fileno())
os.dup2(w, sys.stderr.fileno())
Run Code Online (Sandbox Code Playgroud)

然后从r读


小智 5

实际上,如果您使用的是linux / mac os,则只需使用文件重定向即可。例如,如果您要运行“ a.py”并将其生成的所有消息记录到文件“ a.out”中,则将

python a.py 2>&1 > a.out

第一部分将stderr重定向到stdout,第二部分将其重定向到名为a.out的文件。

有关Linux / Unix中重定向操作符的更多列表,请参见https://askubuntu.com/questions/420981/how-do-i-save-terminal-output-to-a-file


max*_*max 5

从 python 3.5 开始你可以使用contextlib.redirect_stderr

with open('help.txt', 'w') as f:
    with redirect_stdout(f):
        help(pow)
Run Code Online (Sandbox Code Playgroud)

  • 对于那些想要以字符串形式获取输出的人: ` with io.StringIO() as buff: with contextlib.redirect_stderr(buff): help(pow) print(buff.getvalue()) ` (2认同)