代码之家  ›  专栏  ›  技术社区  ›  Mad Physicist

从C/C++库中抑制stdout消息

  •  1
  • Mad Physicist  · 技术社区  · 9 月前

    我试图抑制用C实现的库打印到stdout的消息。

    我的具体用例是OpenCV,所以我将在下面的MCVE中使用它。这个 estimateChessboardSharpness 当网格尺寸太小时(这种情况会发生),函数会打印输出 here ). 我做了一个 PR to fix it ,但与此同时,我想压制这条消息。例如

    import cv2
    import numpy as np
    
    img = np.zeros((512, 640), dtype='uint8')
    corners = []
    for i in range(10):
        for j in range(8):
            corner = (30 + 3 * j, 70 + 3 * i)
            if i and j:
                corners.append(corner)
            if (i % 2) ^ (j % 2):
                img[corner[0]:corner[0] + 3, corner[1]:corner[1] + 3] = 255
    corners = np.array(corners)
    
    >>> cv2.estimateChessboardSharpness(img, (9, 7), corners)
    calcEdgeSharpness: checkerboard too small for calculation.
    ((9999.0, 9999.0, 9999.0, 9999.0), None)
    

    这条线似乎很简单 std::cout << ... ,所以我尝试了以下所有方法:

    from contextlib import redirect_stdout
    from os imoprt devnull
    import sys
    
    with redirect_stdout(None):
        cv2.estimateChessboardSharpness(img, (9, 7), corners)
    
    with open(devnull, "w") as null, redirect_stdout(null):
        cv2.estimateChessboardSharpness(img, (9, 7), corners)
    
    sys.stdout = open(devnull, "w")
    cv2.estimateChessboardSharpness(img, (9, 7), corners)
    

    我甚至试过 redirect_stderr 而不是 redirect_stdout 以防万一。我也试过设置 OPENCV_LOG_LEVEL=SILENT 在bash和 os.environ["OPENCV_LOG_LEVEL"] = "SILENT" 导入前在python中 cv2 ,我并没有预料到在这种情况下stdout会与日志记录混为一谈。

    在所有情况下,消息都会打印出来。我该怎么让它停下来?

    1 回复  |  直到 9 月前
        1
  •  1
  •   Useless    9 月前

    假设一个类UNIX平台,(你会得到一个 OSError 如果没有)

    您可以使用以下命令保存底层fd

    backup = os.dup(sys.stdout.fileno())
    

    将其指向另一个文件(例如。 different 具有

    os.dup2(different.fileno(), sys.stdout.fileno())
    

    并恢复正常服务

    os.dup2(backup, sys.stdout.fileno())
    

    请注意,如果您重定向到的文件也用于缓冲输出(即,您对 不同的 与C++库混合写入 std::cout 这是使用 different.fileno() ...)