Python 从check_输出中抑制标准输出,但将其写入日志
我有以下代码:Python 从check_输出中抑制标准输出,但将其写入日志,python,logging,subprocess,stdout,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()失败时,我想抑制来自标准输出的消息,但将其写入我的记录器 此时,标准输出错误消息会弄乱我的tqdm进度条: [hobbes3@
try:
subprocess.check_output(command.split())
except subprocess.CalledProcessError as e:
count_failure.increment()
logger.error(e.__dict__)
return
当check_output()
失败时,我想抑制来自标准输出的消息,但将其写入我的记录器
此时,标准输出错误消息会弄乱我的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]
这是因为您正在运行的命令正在向标准错误流发出错误消息
check_output
仅捕获标准输出,除非使用额外参数。因此,要么:
subprocess.check_output(command.split(),stderr=subprocess.STDOUT)
因此,输出中也存在错误,或者(python 3):
以完全抑制此错误消息
要获得包含标准错误的正确异常消息,您必须将错误流重定向到特定管道,这样您就不会有stderr=None
subprocess.check_output(command.split(),stderr=subprocess.PIPE)
但这可能会导致输出流和错误流之间的死锁(取决于程序输出到输出或错误的方式,如果管道没有以智能方式读取(例如:使用线程),则在读取另一个空管道时,一个写入可能会因缓冲区满而阻塞) 也许在您的情况下,最好使用
subprocess.Popen
和communicate
,它可以很好地处理这种情况(使用线程或任何在下面工作的东西)
(并保持相同的异常处理)重定向
stderr
subprocess.check_output(command.split(),stderr=subprocess.STDOUT)
如何捕获无法打开文件的确切消息:path='/mnt/data/samples/irs\u 990/foo.xml'error='Permission denied'到记录器
那么?没关系,e
现在得到了整个错误:2018-12-06 21:51:40[错误](线程-11){'returncode':22,'cmd':['/opt/splunk/bin/splunk','add','oneshot','/mnt/data/samples/irs_990/foo.xml','-index','main',''-sourcetype','irs_990'],'output':b“无法打开文件:路径='/mnt/data/samples/irs_990/foo.xml'错误='权限被拒绝'\n','stderr','None}
。谢谢如果你对错误的出现没意见,那没关系。除此之外,我还提供了更多alternatives@Jean-Françoisfar为什么将错误流重定向到管道会导致死锁?根据程序输出到输出或错误的方式,如果管道没有以智能方式读取(例如:使用线程),则在读取另一个空管道时,一个写入可能会因缓冲区已满而阻塞。它可能会导致死锁,而不是一直都是100%
subprocess.check_output(command.split(),stderr=subprocess.DEVNULL)
subprocess.check_output(command.split(),stderr=subprocess.PIPE)
p = subprocess.Popen(command.split(),stderr=subprocess.PIPE,stdout=subprocess.PIPE)
output,error = p.communicate()