苏泽湛 发表于 2018-8-11 11:19:44

python 获取Dmidecode 输出的系统硬件信息

  目的:
  熟悉利用python 分析文本的信息。分析的文件信息是通过dmidecode 工具抓取的系统硬件信息。
  本文结构:
  (1) 分析dmidecode 工具的输出信息结构
  (2) 分别用两种方式对dmidecode 输出的信息实现抓取,获取Manufacturer、Product Name和 Serial Number.

[*]  dmidecode 输出信息分析
  dmidecode 是系统的工具,如果没有安装,需要先安装。在我的机器上的Dmidecode 版本:

  安装的方式也很简单,用命令:yuminstall -ydmidecode 即可。
  Dmidecode 工具主要是将系统的DMI数据库的信息进行解码,并以可读的信息显示。输出的信息包括了BIOS、系统、主板、处理器、内存、缓存、序列号、产品名称和厂家信息等。DMI就是收集系统信息的管理系统,它遵循SMBOIS协议,是主板制造商需严格遵守的协议。
  dmidecode 输出的信息比较多,一屏并不能显示完整,只能用"dmidecode| less" 处理一下:

  这篇文章需要处理收集的信息在"System Information" 这部分:

  2. 方法实现
  回到这篇文章讨论的目的,python 的实现方式就是:
  (1) 执行命令"dmidecode" ,将它的输出信息读出并保存。使用python 的subprocess 模块。
  (2) 然后遍历文本。
  根据遍历文本的方式,给出两个实现的版本:
  版本1:对dmidecode 信息整体保存,然后逐行遍历
#!/usr/bin/envpython  

  
"""
  
file_name: dmi.py
  
"""
  

  
fromsubprocessimport   Popen, PIPE
  

  
p = Popen(["dmidecode"], stdout=PIPE, stderr=PIPE)
  
line_in = False
  
lines = []
  
dmi_dic = {}
  

  
while True:
  
   line=p.stdout.readline()   #逐行遍历
  
   ifline.startswith('System Information'):   #找到了"System Information" 的开始
  
       line_in = True
  
       continue
  
   if line_in:
  
       if line!= ‘\n’:#在"System Information" 里遍历
  
         lines.append(line)
  
       else:
  
         break   #如果到了"System Information" 的换行,则退出while 循环
  

  
printlines
  暂时,先看这部分的输出结果:

  如图,输出的列表,最好能将它变成字典保存,变成字典的形式就很方便输出了。转换成字典时,需要将每个元素头尾的'\t'和'\n'去除,然后按":"符号分割,分别就是字典的key 和value了。继续完善上面的脚本,为了完整性,脚本还是会从开始给出:
#!/usr/bin/envpython  

  
"""
  
file_name: dmi.py
  
"""
  

  
fromsubprocessimport   Popen, PIPE
  

  
p = Popen(["dmidecode"], stdout=PIPE, stderr=PIPE)
  
line_in = False
  
lines = []
  
dmi_dic = {}
  

  
while True:
  
   line=p.stdout.readline()   #逐行遍历
  
   ifline.startswith('System Information'):   #找到了"System Information" 的开始
  
       line_in = True
  
       continue
  
   if line_in:
  
       if line!= ‘\n’:#在"System Information" 里遍历
  
         lines.append(line)
  
       else:
  
         break   #如果到了"System Information" 的换行,则退出while 循环
  

  
#printlines
  

  
"""
  
这里用到列表生成式,遍历lines, 对元素i 去除头尾的'\t'和'\n',然后以‘:’分割,得到两个元素的列表,
  
对于[['a', '1'], ['b', '2']]这种形式的列表,用dict()方法就可以构造出一个字典,如下:
  
"
  
dmi_dic = dict()
  

  
"""现在的dmi_dic 字典已经很接近最终的结果了,但是它的每个value 的最前面还带有空格,所以还需要将value 前的空格去除"""
  
for   k,vindmi_dic.items():
  
    dmi_dic= v.strip()
  

  
"""最后找到需要的Manufacturer、Product Name和 Serial Number的值"""
  
dmi = {}
  
dmi['Manufacturer']=dmi_dic['Manufacturer']
  
dmi['Product Name']=dmi_dic['Product Name']
  
dmi['Serial Number'] =dmi_dic['Serial Number']
  

  
printdmi
  最后,验证结果:

  如图,已经将需要的三个数据保存到字典里了。
  版本2:对dmidecode 信息整体进行分割,然后以列表的形式进行分析
#!/usr/bin/envpython  

  
"""
  
file_name: dmi_t.py
  
"""
  

  
from subprocess import Popen, PIPE
  

  
defgetData():
  
    p = Popen(['dmidecode'], stdout=PIPE, stderr=PIPE)
  
    data = p.stdout.read().split()
  
    return data
  

  

  
if__name__ == '__main__':
  
    print getData()
  执行脚本,先验证一下,输出的结果是什么样子的:

  如图,列表的每一个元素就是dmidecode 的每一行,在上图找到了"System Information" 的这一行。"System Information\n" 的下一行是以'\t'开头的,对应就是原来dmidecode 的缩进的空格。再一直往下看,就会找到'\n'它对应着"System Information"结束后的换行。接着看到'Handle 0x0002...' 这是新的一段信息了。那么,抓取信息就可以用'\t'作为判断了。
  这里有一个判断的技巧要说明一下,例如: 如果a='wedf', 则not a.strip() 返回的是False. 如果a='\n' , 那么not a.strip() 就返回True. 也就是说,字符串进行strip() 方法后,如果还是空字符则not a.strip() 就返回True,如果不为空,则not a.strip() 返回False. 现在继续完善脚本:
#!/usr/bin/envpython  

  
"""
  
file_name: dmi_t.py
  
"""
  

  
from subprocess import Popen, PIPE
  

  
defgetData():
  
    p = Popen(['dmidecode'], stdout=PIPE, stderr=PIPE)
  
    data = p.stdout.read().split()
  
    return data
  

  
defparseData(data):
  
    line_in = False
  
    lines = []
  
    for linein data:
  
      if line.starswith('System Information'):
  
            line_in = True
  
            continue
  
      if line_in:
  
            if not line.strip():#如果遍历到空行,即新的一段信息前,则可以退出循环了
  
                break
  
            else:
  
                lines.append(line)
  

  
defgetDmi(lines):
  
    dmi_dic = {}
  
    dmi = {}
  
    dmi_dic = dict()
  
    for k, v in dmi_dic.items():
  
      dmi_dic = v.strip()
  

  
    dmi['Manufacturer'] = dmi_dic['Manufacturer']
  
    dmi['Product Name'] = dmi_dic['Product Name']
  
    dmi['Serial Number'] = dmi_dic['Serial Number']
  

  
    return dmi
  

  
if__name__ == '__main__':
  
    data   =getData()
  
    lines = parseData(data)
  
    print getDmi(lines)
  看结果:

  总结:
  熟悉利用python 脚本对字符文本信息的处理方法
页: [1]
查看完整版本: python 获取Dmidecode 输出的系统硬件信息