Python调用ipmitool fru -v命令无法获取完整输出的问题排查
问题分析与解决方法
核心问题
你的subprocess调用参数写法错误,导致2> /dev/null被当成了ipmitool的命令参数,而非shell的错误输出重定向,这直接导致命令执行异常,拿不到正常输出。另外,ipmitool本身在执行ipmitool fru print 1 -v时会触发段错误(返回码139/-11都是SIGSEGV信号的表现),但直接执行时能先输出内容再崩溃,而参数错误让subprocess调用连这部分内容都捕获不到。
解决方案
1. 正确处理错误输出重定向
不要把shell重定向符号放进命令列表,改用subprocess的stderr参数来实现:
import subprocess cmd = ['ipmitool', 'fru', 'print', '1', '-v'] # 把stderr重定向到/dev/null with open('/dev/null', 'w') as dev_null: proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=dev_null) # 读取stdout内容,即使进程崩溃也能拿到已输出的部分 output, _ = proc.communicate() print(output.decode()) print(f"返回码: {proc.returncode}")
或者如果必须用shell解析(不推荐,存在安全风险),可以把命令写成字符串并设置shell=True:
import subprocess cmd = 'ipmitool fru print 1 -v 2> /dev/null' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) output, _ = proc.communicate() print(output.decode()) print(f"返回码: {proc.returncode}")
2. 捕获崩溃前的输出
因为ipmitool是先输出内容再触发段错误,communicate()方法会等待进程结束并读取所有已输出到stdout的内容,所以即使进程崩溃,也能拿到你需要的产品制造商、电源供应记录等信息。
额外说明
返回码-11对应Linux的SIGSEGV(段错误),和直接执行时的139本质是同一个信号(139=128+11),这说明ipmitool的-v参数结合fru print 1存在bug,如果你不需要verbose日志,建议去掉-v参数,避免触发段错误:
cmd = ['ipmitool', 'fru', 'print', '1'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = proc.communicate() print(output.decode())
内容的提问来源于stack exchange,提问作者boomerang
相关产品推荐
相关产品推荐

