手机版
你好,游客 登录 注册
背景:
阅读新闻

Python 提取Linux的硬件信息

[日期:2018-11-26] 来源:Linux社区  作者:brianzhu [字体: ]

使用Python实现提取Linux的硬件信息的代码及解析。

1、代码实现目的

注:代码可以直接粘贴使用

为了实现对主机的整体有明确的了解,实现了下面的代码功能

代码主要功能是:

提取到主机的内存、硬盘、CPU、型号等信息

插入到mysql的数据库中

回到顶部

2、代码具体实现步骤

2.1首先要先在mysql中新建数据库和数据表

新建数据库:

create database host;

新建数据表:

CREATE TABLE `host_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product` varchar(255) DEFAULT NULL,
  `cpu_num` varchar(255) DEFAULT NULL,
  `hostname` varchar(255) DEFAULT NULL,
  `ip_out` varchar(255) NOT NULL DEFAULT '',
  `cpu_model` varchar(255) DEFAULT NULL,
  `ip_in` varchar(255) DEFAULT NULL,
  `osver` varchar(255) DEFAULT NULL,
  `sn` varchar(255) DEFAULT NULL,
  `Memory` varchar(255) DEFAULT NULL,
  `vender` varchar(255) DEFAULT NULL,
  `Disk` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`,`ip_out`),
  UNIQUE KEY `ip_out` (`ip_out`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;

2.2 下面就是具体获取硬件信息的代码:

#!/usr/bin/env python
# encoding: utf-8
 
'''
收集主机的信息:
主机名称、IP、系统版本、服务器厂商、型号、序列号、CPU信息、内存信息
'''
 
from subprocess import Popen, PIPE
import os, sys
import socket, fcntl, struct
from collections import namedtuple
import pymysql
import re
 
'''获取所以磁盘信息'''
 
disk_ntuple = namedtuple('partition', 'device mountpoint fstype')
usage_ntuple = namedtuple('usage', 'total used free percent')
 
 
''' 获取 ifconfig 命令的输出 '''
 
def getIfconfig():
    p = Popen(['ifconfig'], stdout=PIPE)
    data = p.stdout.read()
    return data
 
 
''' 获取 dmidecode 命令的输出 '''
 
def getDmi():
    p = Popen(['dmidecode'], stdout=PIPE)
    data = p.stdout.read()
    return data
 
 
'''获取磁盘总大小  格式sda[300GB]+sdb[300GB]'''
 
def humanize_bytes(bytesize, precision=0):
    abbrevs = (
        (10**15, 'PB'),
        (10**12, 'TB'),
        (10**9, 'GB'),
        (10**6, 'MB'),
        (10**3, 'kB'),
        (1, 'bytes')
    )
    if bytesize == 1:
        return '1 byte'
    for factor, suffix in abbrevs:
        if bytesize >= factor:
            break
    return '%.*f%s' % (precision, round(float(bytesize) / factor), suffix)
 
def dev_phy_size():
  with open('/proc/partitions','r') as dp:
    res = ''
    for disk in dp.readlines():
      if re.search(r'[s,h,v]d[a-z]\n',disk):
        blknum = disk.strip().split(' ')[-2]
        dev = disk.strip().split(' ')[-1]
        size = int(blknum)*1024
        consist = dev+'['+humanize_bytes(size).strip()+']'
        res += consist + '+'
    return {'Disk':res[:-1]}
 
 
# '''获取分区路径和挂载、格式信息'''
# def disk_partitions(all=False):
#    """Return all mountd partitions as a nameduple.
#    If all == False return phyisical partitions only.
#    """
#    phydevs = []
#    f = open("/proc/filesystems", "r")
#    for line in f:
#        if not line.startswith("nodev"):
#            phydevs.append(line.strip())
#
#    retlist = []
#    f = open('/etc/mtab', "r")
#    for line in f:
#        if not all and line.startswith('none'):
#            continue
#        fields = line.split()
#        device = fields[0]
#        mountpoint = fields[1]
#        fstype = fields[2]
#        if not all and fstype not in phydevs:
#            continue
#        if device == 'none':
#            device = ''
#        ntuple = disk_ntuple(device, mountpoint, fstype)
#        retlist.append(ntuple)
#    return retlist
#
#
#
# '''获取磁盘的使用情况(总、已用、可用、百分比)'''
# def disk_usage(path):
#    """Return disk usage associated with path."""
#    hd = {}
#    st = os.statvfs(path)
#    free = (st.f_bavail * st.f_frsize)
#    total = (st.f_blocks * st.f_frsize)
#    used = (st.f_blocks - st.f_bfree) * st.f_frsize
#    try:
#        percent = ret = (float(used) / total) * 100
#    except ZeroDivisionError:
#        percent = 0
#    hd['total'] = total
#    hd['used'] = used
#    hd['free'] = free
#    hd['percent'] = round(percent, 1)
#    return hd
#
#
# def access_disk():
#    hd = {}
#    disks = disk_partitions()
#    for i in disks:
#        d = list(i)[1]
#        a_disks = disk_usage(d)
#        hd["cipan"] = a_disks
#    return hd
 
''' 根据空行分段落 返回段落列表'''
 
 
def parseData(data):
    parsed_data = []
    new_line = ''
    data = [i for i in data.split('\n') if i]
    for line in data:
        if line[0].strip():
            parsed_data.append(new_line)
            new_line = line + '\n'
        else:
            new_line += line + '\n'
    parsed_data.append(new_line)
    return [i for i in parsed_data if i]
 
 
''' 根据输入的段落数据分析出ifconfig的每个网卡ip信息 '''
 
'''外网IP'''
def parseIfconfig_out(ifname):
    dic = {}
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    ipaddr = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])
    dic['ip_out'] = ipaddr
    return dic
'''内网IP'''
def parseIfconfig_in(ifname):
    dic = {}
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    ipaddr = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])
    dic['ip_in'] = ipaddr
    return dic
 
 
''' 根据输入的dmi段落数据 分析出指定参数 '''
 
 
def parseDmi(parsed_data):
    dic = {}
    parsed_data = [i for i in parsed_data if i.startswith('System Information')]
    parsed_data = [i for i in parsed_data[0].split('\n')[1:] if i]
    dmi_dic = dict([i.strip().split(':') for i in parsed_data])
    dic['vender'] = dmi_dic['Manufacturer'].strip()
    dic['product'] = dmi_dic['Product Name'].strip()
    dic['sn'] = dmi_dic['Serial Number'].strip()
    return dic
 
 
''' 获取Linux系统主机名称 '''
 
 
def getHostname():
    p = Popen(['hostname'], stdout=PIPE)
    data = p.stdout.read().split('\n')[0]
    return {'hostname': data}
 
 
''' 获取Linux系统的版本信息 '''
 
def getOsVersion():
    with open('/etc/issue') as fd:
        for line in fd:
            osver = line.strip()
            break
    return {'osver': osver}
 
 
''' 获取CPU的型号和CPU的核心数 '''
 
 
def getCpu():
    num = 0
    with open('/proc/cpuinfo') as fd:
        for line in fd:
            if line.startswith('processor'):
                num += 1
            if line.startswith('model name'):
                cpu_model = line.split(':')[1].strip().split()
                cpu_model = cpu_model[0] + ' ' + cpu_model[2] + ' ' + cpu_model[-1]
    return {'cpu_num': num, 'cpu_model': cpu_model}
 
 
''' 获取Linux系统的总物理内存 '''
 
 
def getMemory():
    with open('/proc/meminfo') as fd:
        for line in fd:
            if line.startswith('MemTotal'):
                mem = int(line.split()[1].strip())
                break
    mem = '%.f' % (mem / 1024000.0) + ' GB'
    return {'Memory': mem}
 
 
 
 
def main():
    dic = {}
    data_ip = getIfconfig()
    parsed_data_ip = parseData(data_ip)
    ip_out = parseIfconfig_out(sys.argv[1])
    ip_in = parseIfconfig_in(sys.argv[2])
 
    data_dmi = getDmi()
    parsed_data_dmi = parseData(data_dmi)
    dmi = parseDmi(parsed_data_dmi)
 
    acc_disks = dev_phy_size()
    # print acc_disks
 
    hostname = getHostname()
    osver = getOsVersion()
    cpu = getCpu()
    mem = getMemory()
 
    dic.update(ip_in)
    dic.update(ip_out)
    dic.update(dmi)
    dic.update(hostname)
    dic.update(osver)
    dic.update(cpu)
    dic.update(mem)
    dic.update(acc_disks)
    return dic
 
 
def db_connect():
    conn = pymysql.connect(host="x.x.x.x",
                          db='xxxxx',
                          user="root",
                          passwd="*******",
                          charset="utf8")
    cur = conn.cursor()
    return conn,cur
 
def save_mysql(conn, cur, dic):
    k = dic.keys()
    v = dic.values()
    key = ",".join(k)
    vs = list()
    for i in v:
        vs.append("'%s'" % i)
    values = ",".join(vs)
    # print values, k
    try:
        # sql = "REPLACE INTO host_data(%s) VALUES(%s)" % (key, values)
        sql = "INSERT INTO host_data(%s) VALUES(%s)" % (key, values)
        # print sql
        cur.execute(sql)
        conn.commit()
    except Exception as e:
        # print Exception, ": ", e
        conn.rollback()
 
 
 
if __name__ == '__main__':
    conn, cur = db_connect()
    dic_data = main()
    save_mysql(conn, cur, dic_data)

注:

  • 脚本需要修改  db_connect() 函数的数据库信息  (db参数是数据库的库名)
  • 运行方式:python  脚本名称  外网网卡名称  内网网卡名称(因为每台机器的网卡名称不一样,所以在执行脚本的时候最好的把内外网的网卡名称以传值的形式给到脚本)
  • 比如: python host.py  eth1  eth0

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址https://www.linuxidc.com/Linux/2018-11/155533.htm

linux
相关资讯       Python提取Linux硬件信息 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款