【问题标题】:Disable stderr from external library从外部库禁用标准错误
【发布时间】:2017-07-24 14:28:07
【问题描述】:

我需要禁用某些 *.jar 文件产生的 sys.stderr 消息。

这个*.jar 文件是由subprocess.check_call(cmd) 从外部库(skear2pmml 库)的sklear2pmml 方法__init__.py 调用的。

我知道,我可以通过将库代码更改为以下内容来禁用 stderr:

fnull = open(os.devnull,'w')
subprocess.check_call(cmd,stderr=fnull) 

但是这种尝试导致了我不想要的更改 python 库。如何在没有这种副作用的情况下修复 stderr 输出?

【问题讨论】:

    标签: python subprocess stderr


    【解决方案1】:

    一种选择可能是像这样临时重定向sys.stderr

    old_stderr = sys.stderr
    sys.stderr = open(os.devnull, "w")
    # put your library call here
    sys.stderr = old_stderr
    

    这是假设您不会多次调用该库——我认为这可能是一件相当昂贵的事情。

    EDIT(原来的答案是错误的):

    这实际上有点深——Python 的重定向不会影响进程的 STDERR 文件描述符。您需要关闭并重新打开进程的文件描述符。这在以下博客文章中进行了描述,该文章还提供了一个实现(用于 STDOUT):

    http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/

    我不得不稍微更改博客中的代码以使其适用于我的 Python 版本,我正在添加受影响的行:

    # Create a new sys.stdout that points to the redirected fd
    import codecs
    sys.stdout = codecs.getreader("utf-8")(os.fdopen(original_stdout_fd, 'wb'))
    

    【讨论】:

    • 我已经尝试过这个技巧 - 不幸的是,我仍然可以在控制台输出错误消息中看到来自这些 *.jar..
    • 如果我理解正确,这个技巧没有帮助的原因描述了here:“更改这些对象不会影响 os.popen() 执行的进程的标准 I/O 流, os.system() 或 os 模块中的 exec*() 系列函数。”
    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多