代码之家  ›  专栏  ›  技术社区  ›  hobbes3

禁止检查输出的stdout,但将其写入日志

  •  2
  • hobbes3  · 技术社区  · 6 年前

    我有以下代码:

    try:
        subprocess.check_output(command.split())
    except subprocess.CalledProcessError as e:
        count_failure.increment()
        logger.error(e.__dict__)
        return
    

    什么时候? check_output() 失败,那么我想禁止来自stdout的消息,但将其写入我的 logger 相反。

    现在,stdout错误消息把我的 tqdm 进度条:

    [hobbes3@hobbes3 bin]$ ./mass_index.py
    34%|█████████████████████████████████████████▋                                                                                | 13/38 [00:00<00:14,  1.75it/s]
    unable to open file: path='/mnt/data/samples/irs_990/foo.xml' error='Permission denied'
    100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 38/38 [00:02<00:00,  5.96it/s]
    

    另外,实际消息 Permission denied 不存储在里面 e . 我的 e.__dict__ 只说

    {'returncode': 22, 'cmd': ['/opt/splunk/bin/splunk', 'add', 'oneshot', '/mnt/data/samples/irs_990/foo.xml', '-index', 'main', '-sourcetype', 'irs_990'], 'output': b'', 'stderr': None}
    
    1 回复  |  直到 6 年前
        1
  •  5
  •   Jean-François Fabre    6 年前

    这是因为正在运行的命令正在向标准错误流发出错误消息。

    check_output 仅捕获标准 输出 ,除非使用额外的参数。所以:

    subprocess.check_output(command.split(),stderr=subprocess.STDOUT)
    

    所以输出中也有错误,或者(python 3):

    subprocess.check_output(command.split(),stderr=subprocess.DEVNULL)
    

    完全禁止显示此错误消息。

    要获得包含标准错误的正确异常消息,必须将错误流重定向到特定管道,以便 stderr=None

    subprocess.check_output(command.split(),stderr=subprocess.PIPE)
    

    但这可能会导致输出流和错误流之间的死锁(取决于程序输出到输出或错误的方式,如果管道不是以智能方式读取的(例如:使用线程),则在读取另一个为空的管道时,一个写入可能会由于缓冲区满而阻塞。

    也许在你的情况下,你最好 subprocess.Popen communicate 它可以很好地处理这种情况(下面有线程或其他工作方式)

    p = subprocess.Popen(command.split(),stderr=subprocess.PIPE,stdout=subprocess.PIPE)
    output,error = p.communicate()
    

    (并保持相同的异常处理)

    推荐文章