Python 运维 ------ 系统信息模块
作用:采集服务器 CPU、内存、磁盘、网络、进程、IP 网段信息,用于监控、巡检、自动化运维。 包含三大模块:psutil(系统资源采集)、IPy(IP 网段处理)、subprocess.Popen(调用系统命令)
一、psutil 模块(跨平台系统资源采集)
1. 简介
psutil 是第三方跨平台库,用来获取系统利用率、进程信息,等价于 Linux 命令top、free、df、ps、iostat等工具的能力。 安装:
pip install psutil
2. CPU 信息
表格
| 方法 | 说明 |
|---|---|
psutil.cpu_times() |
获取 CPU 各项时间统计(user、system、idle、iowait 等) |
psutil.cpu_times(percpu=True) |
获取每个逻辑 CPU 的详细时间 |
psutil.cpu_count() |
CPU 逻辑核数(包含超线程) |
psutil.cpu_count(logical=False) |
CPU 物理核数 |
示例代码
python
import psutil
cpu_info = psutil.cpu_times(percpu=True)
print(cpu_info)
print('user CPU时间:',psutil.cpu_times().user)
print('逻辑核:',psutil.cpu_count())
print('物理核:',psutil.cpu_count(logical=False))
3. 内存信息
psutil.virtual_memory():物理内存信息,返回对象包含total、used、free、available、percentpsutil.swap_memory():swap 交换分区信息
python
import psutil
mem = psutil.virtual_memory()
print("内存总大小",mem.total)
print("空闲内存",mem.free)
print("swap信息",psutil.swap_memory())
单位:返回数值单位是字节 Byte,需要手动除以 1024 转 KB、MB。
4. 磁盘信息
表格
| 方法 | 作用 |
|---|---|
psutil.disk_partitions() |
获取磁盘分区列表 |
psutil.disk_usage('/') |
获取某个分区使用率 |
psutil.disk_io_counters() |
磁盘整体 IO 统计 |
psutil.disk_io_counters(perdisk=True) |
每块磁盘单独 IO 统计 |
python
import psutil
print(psutil.disk_partitions())
print(psutil.disk_usage('/'))
print(psutil.disk_io_counters())
5. 网络 IO 信息
表格
| 方法 | 说明 |
|---|---|
psutil.net_io_counters() |
整机全部网卡收发流量包、字节数 |
psutil.net_io_counters(pernic=True) |
每个网卡单独流量统计 |
返回字段:bytes_sent发送字节、bytes_recv接收字节、packets_sent发送包、packets_recv接收包。
6. 其他系统基础信息
python
import psutil,datetime
psutil.users() # 当前登录系统用户列表
psutil.boot_time() # 开机时间戳(1970‑01‑01开始的秒数)
# 时间戳转可读时间
datetime.datetime.fromtimestamp(psutil.boot_time()).strftime('%Y-%m-%d %H:%M:%S')
7. 进程管理
psutil.pids():获取全部进程 PID 列表psutil.Process(pid):实例化单个进程对象,获取进程各项信息
Process 对象常用方法:
python
p = psutil.Process(2000)
p.name() #进程名
p.exe() #程序二进制路径
p.cwd() #工作目录
p.status() #进程状态
p.create_time() #进程创建时间戳
p.uids() #UID信息(Linux)
p.gids() #GID信息(Linux)
p.cpu_times() #进程CPU占用时间
p.memory_percent()#进程内存占比
p.memory_info() #rss、vms内存详情
p.io_counters() #进程IO读写统计
p.num_threads() #线程数量
8.subprocess.Popen 调用系统命令
Popen 是底层创建子进程类,用来执行 shell 命令,获取输出和错误信息。
stdout=subprocess.PIPE:捕获标准输出stderr=subprocess.PIPE:捕获错误输出.communicate():等待命令执行完成,返回(输出字节,错误字节),返回是 bytes,需要.decode("utf‑8")转字符串。
示例:
python
import subprocess
process = subprocess.Popen(['ls','-l'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output,error = process.communicate()
if output:
print(output.decode('utf‑8'))
if error:
print(error.decode('utf‑8'))
注意:命令建议写成列表
["ls","‑l"],不推荐字符串 + shell=True,存在安全风险。
二、IPy 模块(IP 地址网段处理)
第三方模块,用于 IP 规划,处理 IPv4/IPv6 网段、掩码、IP 区间计算。 安装:
pip install IPy
导入:from IPy import IP
1. 基础用法
python
ip = IP('192.168.1.0/24')
ip.version() #4代表IPv4,6代表IPv6
ip.len() #网段内IP总数量
for x in ip: #遍历网段所有IP
print(x)
2.IP 常用转换方法
python
ip=IP('192.168.1.20')
ip.reverseNames() #反向解析域名
ip.iptype() #PRIVATE私网 / PUBLIC公网
ip.int() #转整数
ip.strHex() #十六进制
ip.strBin() #二进制
IP(0x8080808) #十六进制转回IP
3.make_net=True 重点(踩坑点)
-
作用:把 IP / 掩码、IP 范围,强制转为标准网段对象。
-
⚠️重要限制:如果传入
起始IP‑结束IP的范围,必须刚好是完整子网边界,总 IP 数量是 2 的 n 次方,否则抛异常not on a network boundary。#✅合法,刚好/24完整网段
IP('192.168.1.0‑192.168.1.255',make_net=True)
#❌报错,0‑192一共193个IP,不是2的幂次
IP('192.168.1.0‑192.168.1.192',make_net=True)
4.strNormal () 格式化输出网段
IP('192.168.1.0/24').strNormal(wantprefixlen=?)
表格
| 参数值 | 输出格式 |
|---|---|
| 0 | 192.168.1.0(仅网络地址) |
| 1 | 192.168.1.0/24(前缀) |
| 2 | 192.168.1.0/255.255.255.0(点分掩码) |
| 3 | 192.168.1.0‑192.168.1.255(起止 IP) |
5. 网段关系运算
- 判断 IP 是否属于网段:
'192.168.1.100' in IP('192.168.1.0/24') - 网段大小比较:
IP('10.0.0.0/24') < IP('12.0.0.0/24') - 判断网段是否重叠
.overlaps(),返回 1 重叠,0 不重叠
python
IP('192.168.0.0/23').overlaps('192.168.1.0/24') #返回1,重叠
IP('192.168.1.0/24').overlaps('192.168.2.0/24') #返回0,不重叠
6. 综合小案例:输入 IP / 网段输出网络信息
python
address = input('请输入ip地址: ')
ip = IP(address)
if len(ip) > 1:
print('网络号为:',ip.net())
print('子网掩码为:',ip.netmask())
print('广播地址为:',ip.broadcast())
print('反向解析地址:',ip.reverseNames()[0])
print('网络子网数:',len(ip))
else:
print('反向解析ip地址为:',ip.reverseNames()[0])
print('十六进制地址:',ip.strHex())
print('二进制地址:',ip.strBin())
print('地址类型为:',ip.iptype())