python - 从 check_output 抑制标准输出,但将其写入日志
问题描述
我有以下代码:
try:
subprocess.check_output(command.split())
except subprocess.CalledProcessError as e:
count_failure.increment()
logger.error(e.__dict__)
return
当check_output()
失败时,我想从标准输出中抑制该消息,而是将其写入我的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.Popen
并且communicate
可以很好地处理这种情况(使用线程或任何在下面工作的东西)
p = subprocess.Popen(command.split(),stderr=subprocess.PIPE,stdout=subprocess.PIPE)
output,error = p.communicate()
(并保持相同的异常处理)
推荐阅读
- javascript - 使用 functionName() 和仅使用 functionName 分配变量值有什么区别?
- c++ - 输入流似乎无法正常工作
- google-apps-script - 是否可以在松弛频道中删除由谷歌脚本制作的机器人发出的消息?
- combobox - 如何为 ttk::matchbox 的 -matchcommand 编写代码
- php - Wordpress 迁移后主页未加载,所有其他页面加载
- amazon-web-services - EC2 实例是否默认包含 EBS 卷或实例存储?
- c++ - 返回局部变量的引用
- c# - Testrun 无法在 VS2019 中正确启动
- .net-core - FluentMigrator:如何为 MigrationRunner 设置默认架构
- max - 给定一个整数,你的任务是找到另一个整数,使得它们的按位异或最大