如何仅重定向流的一部分?

How can I redirect only part of a stream?

我在 Linux 上的 bash 上使用 Python。我希望能够抑制来自特定模块的错误消息,但保留其他错误消息。一个例子可能是传达我想要的最有效的方式:


文件:module.py

import sys
sys.stderr.write('Undesired output.\n')

文件:script.py

import module
import sys

sys.stderr.write('Desired output.\n')
sys.stdout.write('Desired output.\n')
x = int('a')

运行的输出script.py:

$ python script.py
Undesired output.
Desired output.
Desired output.
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    x = int('a')
ValueError: invalid literal for int() with base 10: 'a'

运行 script.py 的期望输出:

$ python script.py
Desired output.
Desired output.
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    x = int('a')
ValueError: invalid literal for int() with base 10: 'a'

我不能修改module.py,但我必须使用它。我尝试了各种重定向,并打开了新的文件描述符,但我似乎无法从 python 中更改调用 shell 的文件描述符,因此

$ python script.py 2>/dev/null
Desired output.

杀死所有 stderr 输出。因为我知道模块导致了不需要的消息,所以我确切地知道我想停止将 stderr 重定向到 /dev/null 并开始将其重定向到 &1 的点,但我似乎无法能够从 Python.

中完成

非常感谢任何建议!

已接受的答案中有一个示例可能会对您有所帮助

Temporarily Redirect stdout/stderr

但在你的情况下,它假定你可以做到

import module

之后

import sys

之后,您已在 Python 代码中重定向了 stderr。喜欢

import sys

... redirect code here

import module

... code to remove redirect

除了重定向之外,不知道这是否会破坏您想要的功能。

此外,您不应该在代码中间插入 import 语句,因为它违反了 PEP8 风格指南。

一些实验让我找到了这个问题的答案,所以我将接受它。

这样做:

$ exec 3>&1

然后将 script.py 更改为以下内容:

import sys, os
sys.stderr = open(os.devnull, 'w')
import module
sys.stderr = os.fdopen(3, 'w')

sys.stderr.write('Desired output.\n')
sys.stdout.write('Desired output.\n')
x = int('a')

然后 运行 这样:

$ python script.py 2>/dev/null

产生所需的输出。