【发布时间】:2021-08-09 17:21:15
【问题描述】:
我有运行 C 代码的 python 代码,该代码向 stdout 和 stderr 发送垃圾邮件。
我想抑制标准输出和标准错误,但不能修改 C 代码。作为伪代码,大致如下:
def external_api_I_cant_control():
C code that outputs to stdout & stderr # this is not a subprocess
# call which I can redirect
# its stdout & stderr. Rather,
# it's a wrapper for it so there
# is nothing I can do to control its
# FD
def do_stuff():
external_api_I_cant_control()
我的代码正在使用python bla.py 运行,因此我可以使用python bla.py 2>/dev/null 重定向stderr,但这并不能解决我的问题,因为一些垃圾邮件是stdout,我无法重定向stdout - 因为我需要一些。
是否可以在我的代码中执行相当于 shell 标准输出重定向的操作?
到目前为止我试过了:
contextlib.redirect_stdout- 将
sys.stdout和sys.__stdout__替换为open(os.devnull, 'w')
我想要的结果相当于将我的 bla.py 拆分为 3 并像这样运行它:
python bla0.output.is.legit.py
python bla1.output.should.be.disregarded.py &> /dev/null
python bla2.output.is.legit.again.py
实现这一目标的方法是什么?
【问题讨论】:
-
os.dup2()是你的朋友。编写一个使用它的contextlib.redirect_stdout的等价物应该不难。 -
你是如何运行子进程的?你在用
subprocessmodule吗? -
(说 "
subprocesscall I can't control",带有subprocess代码格式,暗示这是一个 Pythonsubprocess库使用,而不仅仅是一个由C代码fork()ing和exec()ing创建的实际子进程。如果你是指后者,请不要对其进行代码格式化以避免错误的含义) -
只说“子进程”,而不是“
subprocess”。当你说subprocess时,这意味着subprocess是代码,而作为 Python 代码,这意味着使用标准库subprocess模块。 -
您可以使用
dup2()将文件描述符复制到另一个已经存在的FD——这样您就可以复制新的/不同的内容over stdout 或 stderr 来替换它。这就是重定向在 C 中的工作方式(以及 shell 如何在后台实现它)。
标签: python stdout io-redirection