python - 从 check_output 中抑制标准输出,而是将其写入日志

标签 python logging subprocess stdout

我有以下代码:

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}

最佳答案

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

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.Popencommunicate 来很好地处理这种情况(使用线程或任何底层工作)

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

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

关于python - 从 check_output 中抑制标准输出,而是将其写入日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53660152/

相关文章:

python - python 是否导入所有列出的库?

python - 编写一个在 matlab 中可读的 3d numpy 数组

ios - 如何阅读这个 ios 符号化的崩溃日志?

java - 事件日志解析器的适当设计模式?

Python 子进程将调用输出存储到文件

python - 将字符串连接到列表字典中的键和值

python - Fabric 3 询问 sudo 密码一次

java - 防止 Java 在某些异常情况下打印堆栈跟踪

python - 杀死进程不杀死子进程并且不关闭终端窗口

python - subprocess.check_output 不接受长参数