Python 快速获得Linux系统和磁盘信息

18 篇文章 0 订阅

背景介绍

在日常运维或者迁移客户系统的时候我们需要快速的了解客户应用系统的主机的一些基本信息,我们可以通过Linux的命令获得相关信息,自己信息总结,我这里收集总结了基于Python2.7的一些脚本,可以快速获得系统的基础信息。选择Python2.7是应为现在绝大多数Linux 操作系统依然使用的默认版本的Python还是2.x的版本。本身这些脚本可以下载直接运行,无需安装任何第三方的包方便使用。

获得操作系统信息

#coding=utf-8

import platform


def GetPlatformInfo():
    print ("----------Operation System--------------------------")
    #  获取Python版本
    # print platform.python_version()

    #   获取操作系统可执行程序的结构,,(’32bit’, ‘WindowsPE’)
    print "操作系统可执行程序的结构: " + str(platform.architecture())

    #   计算机的网络名称,’acer-PC’
    print "主机名称: " + str(platform.node())

    # 获取操作系统名称及版本号,’Windows-7-6.1.7601-SP1′
    print "操作系统名称及版本号: " + str(platform.platform())

    # 计算机处理器信息,’Intel64 Family 6 Model 42 Stepping 7, GenuineIntel’
    print "CPU: " + str(platform.processor())

    # 获取操作系统中Python的构建日期
    # print platform.python_build()

    #  获取系统中python解释器的信息
   #  print platform.python_compiler()

    # if platform.python_branch() == "":
    #     print platform.python_implementation()
    #     print platform.python_revision()

    print "操作系统版本: " + platform.release()
    print "操作系统: " + platform.system()

    # print platform.system_alias()
    #  获取操作系统的版本
    # print platform.version()
    #  包含上面所有的信息汇总
    # print platform.uname()


def UsePlatform():
    sysstr = platform.system()
    if (sysstr == "Windows"):
        print ("Call Windows tasks")
    elif (sysstr == "Linux"):
        print ("Call Linux tasks")
    else:
        print sysstr


if __name__ == "__main__":
    GetPlatformInfo()

输出示例:

----------Operation System--------------------------
操作系统可执行程序的结构: ('64bit', 'ELF')
主机名称: centos-7-3.shared
操作系统名称及版本号: Linux-3.10.0-693.5.2.el7.x86_64-x86_64-with-centos-7.4.1708-Core
CPU: x86_64
操作系统版本: 3.10.0-693.5.2.el7.x86_64
操作系统: Linux

获系统和磁盘挂载信息

此脚本的特点是输出信息通过不同的颜色区分

import os
import sys
import platform
import glob
import re

#####################################HOST INFORMATION
OS_flavour = platform.system()
print "\033[1;36;40mOS Flavour \033[0;37;40m : %s\n" % OS_flavour
OS_distribution = platform.linux_distribution()
print "\033[1;36;40mOS Vendor : \033[0;37;40m %s\t\033[1;36;40m Version : \033[0;37;40m %s\t\033[1;36;40mId \033[0;37;40m: %s\n" % OS_distribution
OS_arch = platform.processor()
print "\033[1;36;40mOS Architecture : \033[0;37;40m %s\n" % OS_arch
Network_hostanme = platform.node()
print "\033[1;36;40mServer\'s Network Hostname :\033[0;37;40m %s\n" % Network_hostanme
Linux_kernel = platform.uname()
print "\033[1;36;40mLinux Kernel Version : \033[0;37;40m %s\n" % Linux_kernel[2]

#######DECLARING SYSFS PATH
sysfs = ["/sys/class/scsi_device/", "/sys/class/scsi_host/", "/sys/devices/", "/sys/block/"]
#######Findins Scsi Device
scsi_device = os.listdir(sysfs[0])
pci_scsi = {}
print "\033[1;36;40mAvailable Scsi Device ID : \033[0;37;40m %s\n" % scsi_device

#######FINDING PCI
for i in scsi_device:
    pci_array = os.readlink(sysfs[0] + i).rsplit("/\\")
    pci_scsi[i] = pci_array[3:5]

    print "\033[1;36;40mMapping OS SCSI ID TO PCI ID \033[0;37;40m"
    print "\033[1;32;40m\tSCSI ID\t\tPCI ID \033[0;37;40m \n"

    for n in pci_scsi:
        print "\t%s\t\t%s" % (n, pci_scsi[n])
    print "\n"
    ###Host Adapter and attached Disk information#####
    scsi_host = os.listdir(sysfs[1])
    print "\033[1;36;40mFounded Host adapter :\t \033[0;37;40m %s\n" % scsi_host

输出示例;

OS Flavour  : Linux

OS Vendor :  CentOS Linux	 Version :  7.4.1708	Id : Core

OS Architecture :  x86_64

Server's Network Hostname : centos-7-3.shared

Linux Kernel Version :  3.10.0-693.5.2.el7.x86_64

Available Scsi Device ID :  ['2:0:0:0', '3:0:0:0']

Mapping OS SCSI ID TO PCI ID 
	SCSI ID		PCI ID  

	2:0:0:0		[]


Founded Host adapter :	  ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7']

Mapping OS SCSI ID TO PCI ID 
	SCSI ID		PCI ID  

	2:0:0:0		[]
	3:0:0:0		[]


Founded Host adapter :	  ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7']

获取磁盘信息-分区、挂载点

#!/usr/bin/python

import os
import re
import sys
import errno
from subprocess import Popen,PIPE

def find_device(data, pciid):
    id = re.escape(pciid)
    m = re.search("^" + id + "\s(.*)$", data, re.MULTILINE)
    return m.group(1)

def pretty_size(size):
    size_strs = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
    last_size = size
    fract_size = size
    num_divs = 0

    while size > 1:
        fract_size = last_size
        last_size = size
        size /= 1024
        num_divs += 1

    num_divs -= 1
    fraction = fract_size / 1024
    pretty = "%.2f" % fraction
    pretty = pretty + size_strs[num_divs]
    return pretty

def virtual_device(path):
    for dir in os.listdir(path):
        if re.search("device", dir):
            return 0
    return 1

class Device:
    def __init__(self):
        self.sectorsize = ""
        self.sectors = ""
        self.rotational = ""
        self.sysdir = ""
        self.host = ""
        self.model = ""
        self.vendor = ""
        self.holders = []
        self.diskname = ""
        self.partitions = []
        self.removable = ""
        self.start = ""
        self.discard = ""
        self.sysfs_no_links = 0

    def populate_model(self):
        try:
            f = open(self.sysdir + "/device/model")
            self.model = f.read().rstrip()
            f.close()
        except IOError:
            # do nothing
            pass

    def populate_vendor(self):
        try:
            f = open(self.sysdir + "/device/vendor")
            self.vendor = f.read().rstrip()
            f.close()
        except IOError:
            #do nothing
            pass

    def populate_sectors(self):
        try:
            f = open(self.sysdir + "/size")
            self.sectors = f.read().rstrip()
            f.close()
        except IOError:
            self.sectors = 0

    def populate_sector_size(self):
        try:
            f = open(self.sysdir + "/queue/hw_sector_size")
            self.sectorsize = f.read().rstrip()
            f.close()
        except IOError:
            # if this sysfs doesnt show us sectorsize then just assume 512
            self.sectorsize = "512"

    def populate_rotational(self):
        try:
            f = open(self.sysdir + "/queue/rotational")
            rotation = f.read().rstrip()
            f.close()
        except IOError:
            self.rotational = "Could not determine rotational"
            return
        if rotation == "1":
            self.rotational = "Spinning disk"
        else:
            self.rotational = "SSD"

    def populate_host(self, pcidata):
        if self.sysfs_no_links == 1:
            try:
                sysdir = os.readlink(os.path.join(self.sysdir, "device"))
            except:
                pass
        else:
            sysdir = self.sysdir
        m = re.match(".+/\d+:(\w+:\w+\.\w)/host\d+/\s*", sysdir)
        if m:
            pciid = m.group(1)
            self.host = find_device(pcidata, pciid)
        else:
            self.host = ""

    def populate_diskname(self):
        m = re.match(".*/(.+)$", self.sysdir)
        self.diskname = m.group(1)

    def populate_holders(self):
        for dir in os.listdir(self.sysdir + "/holders"):
            if re.search("^dm-.*", dir):
                try:
                    f = open(self.sysdir + "/holders/" + dir + "/dm/name")
                    name = f.read().rstrip()
                    f.close()
                    self.holders.append(name)
                except IOError:
                    self.holders.append(dir)
            else:
                self.holders.append(dir)

    def populate_discard(self):
        try:
            f = open(self.sysdir + "/queue/discard_granularity")
            discard = f.read().rstrip()
            f.close()
            if discard == "0":
                self.discard = "No"
            else:
                self.discard = "Yes"
        except IOError:
            self.discard = "No"

    def populate_start(self):
        try:
            f = open(self.sysdir + "/start")
            self.start = f.read().rstrip()
            f.close()
        except IOError:
            pass

    def populate_partitions(self):
        for dir in os.listdir(self.sysdir):
            m = re.search("(" + self.diskname + "\d+)", dir)
            if m:
                partname = m.group(1)
                part = Device()
                part.sysdir = self.sysdir + "/" + partname
                part.populate_part_info()
                self.partitions.append(part)

    def populate_part_info(self):
        """ Only call this if we are a partition """
        self.populate_diskname()
        self.populate_holders()
        self.populate_sectors()
        self.populate_start()

    def populate_removable(self):
        try:
            f = open(self.sysdir + "/removable")
            remove = f.read().rstrip()
            f.close()
            if remove == "1":
                self.removable = "Yes"
            else:
                self.removable = "No"
        except IOError:
            self.removable = "No"

    def populate_all(self, pcidata):
        self.populate_diskname()
        self.populate_holders()
        self.populate_partitions()
        self.populate_removable()
        self.populate_model()
        self.populate_vendor()
        self.populate_sectors()
        self.populate_sector_size()
        self.populate_rotational()
        self.populate_discard()
        self.populate_host(pcidata)

p = Popen(["lspci"], stdout=PIPE)
err = p.wait()
if err:
    print "Error running lspci"
    sys.exit()
pcidata = p.stdout.read()

sysfs_no_links = 0
devices = []

if len(sys.argv) > 1:
    m = re.match("/dev/(\D+)\d*", sys.argv[1])
    if m:
        block = m.group(1)
    else:
        block = sys.argv[1]

    try:
        path = os.readlink(os.path.join("/sys/block/", block))
    except OSError, e:
        if e.errno == errno.EINVAL:
            path = block
        else:
            print "Invalid device name " + block
            sys.exit()
    d = Device()
    d.sysdir = os.path.join("/sys/block", path)
    d.populate_all(pcidata)
    devices.append(d)
else:
    for block in os.listdir("/sys/block"):
        try:
            if sysfs_no_links == 0:
                path = os.readlink(os.path.join("/sys/block/", block))
            else:
                path = block
        except OSError, e:
            if e.errno == errno.EINVAL:
                path = block
                sysfs_no_links = 1
            else:
                continue
        if re.search("virtual", path):
            continue
        if sysfs_no_links == 1:
            sysdir = os.path.join("/sys/block", path)
            if virtual_device(sysdir) == 1:
                continue
        d = Device()
        d.sysdir = os.path.join("/sys/block", path)
        d.sysfs_no_links = sysfs_no_links
        d.populate_all(pcidata)
        devices.append(d)

for d in devices:
    print d.diskname
    print "\tHost: " + d.host
    print "\tVendor: " + d.vendor
    print "\tModel: " + d.model
    print "\tSector size (bytes): " + d.sectorsize
    print "\tSectors: " + d.sectors
    size = float(d.sectors) * float(d.sectorsize)
    pretty = pretty_size(size)
    print "\tSize: " + pretty
    print "\tRemovable: " + d.removable
    print "\tDisk type: " + d.rotational
    print "\tSupports discard: " + d.discard
    if len(d.holders) > 0:
        print "\tHolders:"
        for h in d.holders:
            print "\t\t" + h
    if len(d.partitions) > 0:
        print "\tPartitions:"
        for p in d.partitions:
            print "\t\t" + p.diskname
            print "\t\t\tStart sector: " + p.start
            print "\t\t\tSectors: " + p.sectors
            size = float(p.sectors) * float(d.sectorsize)
            pretty = pretty_size(size)
            print "\t\t\tSize: " + pretty
            if len(p.holders) > 0:
                print "\t\t\tHolders:"
                for h in p.holders:
                    print "\t\t\t\t" + h

输出示例

输出磁盘信息比直观易理解

sda
	Host: 
	Vendor: ATA
	Model: CentOS Linux 7-0
	Sector size (bytes): 512
	Sectors: 134217728
	Size: 64.00GiB
	Removable: No
	Disk type: SSD
	Supports discard: Yes
	Partitions:
		sda1
			Start sector: 2048
			Sectors: 2097152
			Size: 1024.00MiB
		sda2
			Start sector: 2099200
			Sectors: 132118528
			Size: 63.00GiB
			Holders:
				cl-root
				cl-swap
				cl-home
sr0
	Host: 
	Vendor: 
	Model: Virtual DVD-ROM
	Sector size (bytes): 512
	Sectors: 2097151
	Size: 1024.00MiB
	Removable: Yes
	Disk type: Spinning disk
	Supports discard: No

Python3的一个脚本,需要安装单独的包psutil

import psutil
import platform
from datetime import datetime

def get_size(bytes, suffix="B"):
    """
    Scale bytes to its proper format
    e.g:
        1253656 => '1.20MB'
        1253656678 => '1.17GB'
    """
    factor = 1024
    for unit in ["", "K", "M", "G", "T", "P"]:
        if bytes < factor:
            return f"{bytes:.2f}{unit}{suffix}"
        bytes /= factor
print("="*40, "System Information", "="*40)
uname = platform.uname()
print(f"System: {uname.system}")
print(f"Node Name: {uname.node}")
print(f"Release: {uname.release}")
print(f"Version: {uname.version}")
print(f"Machine: {uname.machine}")
print(f"Processor: {uname.processor}")
# Boot Time
print("="*40, "Boot Time", "="*40)
boot_time_timestamp = psutil.boot_time()
bt = datetime.fromtimestamp(boot_time_timestamp)
print(f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}")
# let's print CPU information
print("="*40, "CPU Info", "="*40)
# number of cores
print("Physical cores:", psutil.cpu_count(logical=False))
print("Total cores:", psutil.cpu_count(logical=True))
# CPU frequencies
cpufreq = psutil.cpu_freq()
print(f"Max Frequency: {cpufreq.max:.2f}Mhz")
print(f"Min Frequency: {cpufreq.min:.2f}Mhz")
print(f"Current Frequency: {cpufreq.current:.2f}Mhz")
# CPU usage
print("CPU Usage Per Core:")
for i, percentage in enumerate(psutil.cpu_percent(percpu=True, interval=1)):
    print(f"Core {i}: {percentage}%")
print(f"Total CPU Usage: {psutil.cpu_percent()}%")
# Memory Information
print("="*40, "Memory Information", "="*40)
# get the memory details
svmem = psutil.virtual_memory()
print(f"Total: {get_size(svmem.total)}")
print(f"Available: {get_size(svmem.available)}")
print(f"Used: {get_size(svmem.used)}")
print(f"Percentage: {svmem.percent}%")
print("="*20, "SWAP", "="*20)
# get the swap memory details (if exists)
swap = psutil.swap_memory()
print(f"Total: {get_size(swap.total)}")
print(f"Free: {get_size(swap.free)}")
print(f"Used: {get_size(swap.used)}")
print(f"Percentage: {swap.percent}%")
# Disk Information
print("="*40, "Disk Information", "="*40)
print("Partitions and Usage:")
# get all disk partitions
partitions = psutil.disk_partitions()
for partition in partitions:
    print(f"=== Device: {partition.device} ===")
    print(f"  Mountpoint: {partition.mountpoint}")
    print(f"  File system type: {partition.fstype}")
    try:
        partition_usage = psutil.disk_usage(partition.mountpoint)
    except PermissionError:
        # this can be catched due to the disk that
        # isn't ready
        continue
    print(f"  Total Size: {get_size(partition_usage.total)}")
    print(f"  Used: {get_size(partition_usage.used)}")
    print(f"  Free: {get_size(partition_usage.free)}")
    print(f"  Percentage: {partition_usage.percent}%")
# get IO statistics since boot
disk_io = psutil.disk_io_counters()
print(f"Total read: {get_size(disk_io.read_bytes)}")
print(f"Total write: {get_size(disk_io.write_bytes)}")
# Network information
print("="*40, "Network Information", "="*40)
# get all network interfaces (virtual and physical)
if_addrs = psutil.net_if_addrs()
for interface_name, interface_addresses in if_addrs.items():
    for address in interface_addresses:
        print(f"=== Interface: {interface_name} ===")
        if str(address.family) == 'AddressFamily.AF_INET':
            print(f"  IP Address: {address.address}")
            print(f"  Netmask: {address.netmask}")
            print(f"  Broadcast IP: {address.broadcast}")
        elif str(address.family) == 'AddressFamily.AF_PACKET':
            print(f"  MAC Address: {address.address}")
            print(f"  Netmask: {address.netmask}")
            print(f"  Broadcast MAC: {address.broadcast}")
# get IO statistics since boot
net_io = psutil.net_io_counters()
print(f"Total Bytes Sent: {get_size(net_io.bytes_sent)}")
print(f"Total Bytes Received: {get_size(net_io.bytes_recv)}")

输出示例

======================================== System Information ========================================
System: Darwin
Node Name: dushibings-MacBook-Pro.local
Release: 19.5.0
Version: Darwin Kernel Version 19.5.0: Tue May 26 20:41:44 PDT 2020; root:xnu-6153.121.2~2/RELEASE_X86_64
Machine: x86_64
Processor: i386
======================================== Boot Time ========================================
Boot Time: 2020/7/13 13:24:16
======================================== CPU Info ========================================
Physical cores: 4
Total cores: 8
Max Frequency: 2900.00Mhz
Min Frequency: 2900.00Mhz
Current Frequency: 2900.00Mhz
CPU Usage Per Core:
Core 0: 49.5%
Core 1: 5.9%
Core 2: 34.3%
Core 3: 4.0%
Core 4: 35.6%
Core 5: 4.0%
Core 6: 31.0%
Core 7: 4.0%
Total CPU Usage: 20.9%
======================================== Memory Information ========================================
Total: 16.00GB
Available: 5.64GB
Used: 9.05GB
Percentage: 64.7%
==================== SWAP ====================
Total: 3.00GB
Free: 1.05GB
Used: 1.95GB
Percentage: 65.0%
======================================== Disk Information ========================================
Partitions and Usage:
=== Device: /dev/disk1s5 ===
  Mountpoint: /
  File system type: apfs
  Total Size: 465.63GB
  Used: 10.41GB
  Free: 156.19GB
  Percentage: 6.3%
=== Device: /dev/disk1s1 ===
  Mountpoint: /System/Volumes/Data
  File system type: apfs
  Total Size: 465.63GB
  Used: 294.30GB
  Free: 156.19GB
  Percentage: 65.3%
=== Device: /dev/disk1s4 ===
  Mountpoint: /private/var/vm
  File system type: apfs
  Total Size: 465.63GB
  Used: 4.00GB
  Free: 156.19GB
  Percentage: 2.5%
Total read: 141.10GB
Total write: 169.03GB
======================================== Network Information ========================================
=== Interface: lo0 ===
  IP Address: 127.0.0.1
  Netmask: 255.0.0.0
  Broadcast IP: None
=== Interface: lo0 ===
=== Interface: lo0 ===
=== Interface: en0 ===
  IP Address: 192.168.100.28
  Netmask: 255.255.255.0
  Broadcast IP: 192.168.100.255
=== Interface: en0 ===
=== Interface: en0 ===
=== Interface: vnic0 ===
  IP Address: 10.211.55.2
  Netmask: 255.255.255.0
  Broadcast IP: 10.211.55.255
=== Interface: vnic0 ===
=== Interface: vnic1 ===
  IP Address: 10.37.129.2
  Netmask: 255.255.255.0
  Broadcast IP: 10.37.129.255
=== Interface: vnic1 ===
=== Interface: en1 ===
=== Interface: en2 ===
=== Interface: en3 ==
=== Interface: en4 ===
Total Bytes Sent: 3.69GB
Total Bytes Received: 27.65GB

总结:

基于Python2.7的脚本实际使用意义最大,可以减少通过单独的命令去获取系统信息,并且基于ansible可以实现批量的系统信息查看,但是python3的脚本获取的信息最全面,大家可以结合自己的需求进行搭配使用。

源码下载: https://github.com/Dushibing/Linux_System_investigate

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值