如何在RHEL上用Python判断网卡是否使用DHCP(不依赖Shell命令)
可行解决方案
方案1:通过NetworkManager的DBus接口获取实时状态
RHEL默认使用NetworkManager管理网络,它通过DBus暴露了所有网络设备的实时配置与状态信息,无需调用外部命令,纯Python即可直接访问,结果能准确反映当前生效的网络配置。
实现思路
- 用Python的
dbus模块连接到系统级的NetworkManager DBus服务。 - 遍历所有网络设备,匹配目标网卡名称。
- 获取该网卡的活跃连接,读取连接的IP配置参数,判断是否启用DHCP。
Python2示例代码
import dbus def is_dhcp_enabled(interface_name): bus = dbus.SystemBus() nm_obj = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') nm_iface = dbus.Interface(nm_obj, 'org.freedesktop.NetworkManager') # 遍历所有网络设备 for dev_path in nm_iface.GetDevices(): dev_obj = bus.get_object('org.freedesktop.NetworkManager', dev_path) dev_props = dbus.Interface(dev_obj, 'org.freedesktop.DBus.Properties') current_dev_name = dev_props.Get('org.freedesktop.NetworkManager.Device', 'Interface') if current_dev_name != interface_name: continue # 获取当前活跃连接 active_conn_path = dev_props.Get('org.freedesktop.NetworkManager.Device', 'ActiveConnection') if not active_conn_path: return False # 读取连接的配置信息 active_conn_obj = bus.get_object('org.freedesktop.NetworkManager', active_conn_path) active_conn_props = dbus.Interface(active_conn_obj, 'org.freedesktop.DBus.Properties') conn_settings_path = active_conn_props.Get('org.freedesktop.NetworkManager.Connection.Active', 'Connection') conn_settings_obj = bus.get_object('org.freedesktop.NetworkManager', conn_settings_path) conn_settings_iface = dbus.Interface(conn_settings_obj, 'org.freedesktop.NetworkManager.Settings.Connection') config = conn_settings_iface.GetSettings() # 检查IPv4是否为DHCP(method为auto表示DHCP) if config.get('ipv4', {}).get('method') == 'auto': return True # 检查IPv6是否为DHCP(按需启用) if config.get('ipv6', {}).get('method') == 'auto': return True return False # 调用示例 print(is_dhcp_enabled('eth0'))
方案2:检查DHCP租约文件(轻量无依赖)
如果系统使用NetworkManager、dhclient或systemd-networkd,DHCP成功获取地址后会生成租约文件,通过检查对应网卡的租约文件是否存在且有效,可间接判断当前是否使用DHCP。
实现思路
- 针对不同网络管理工具,对应不同的租约文件路径:
- NetworkManager:
/var/lib/NetworkManager/dhclient-<interface>.lease - 传统dhclient:
/var/lib/dhclient/dhclient-{interface}.leases - systemd-networkd:
/run/systemd/netif/leases/<数字索引>-<interface>
- NetworkManager:
- 检查目标路径下的文件是否存在,可选验证租约是否未过期。
Python2示例代码
import os import time def check_dhcp_lease(interface_name): # 定义常用租约文件路径模板 lease_candidates = [ '/var/lib/NetworkManager/dhclient-{}.lease'.format(interface_name), '/var/lib/dhclient/dhclient-{}.leases'.format(interface_name), ] # 检查systemd-networkd的租约目录 systemd_lease_dir = '/run/systemd/netif/leases/' if os.path.isdir(systemd_lease_dir): for filename in os.listdir(systemd_lease_dir): if filename.endswith('-{}'.format(interface_name)): lease_candidates.append(os.path.join(systemd_lease_dir, filename)) for path in lease_candidates: if not os.path.exists(path): continue # 可选:验证租约是否未过期 with open(path, 'r') as f: for line in f.readlines(): line = line.strip() if line.startswith('expire'): try: expire_timestamp = int(line.split()[1]) if expire_timestamp > time.time(): return True except (IndexError, ValueError): pass # 若无法解析过期时间,仅以文件存在作为判断依据 return True return False # 调用示例 print(check_dhcp_lease('eth0'))
方案3:使用pyroute2库访问内核Netlink接口
pyroute2是纯Python实现的Linux内核Netlink通信库,可直接从内核获取网络设备的实时配置,无需依赖外部命令,结果精准且轻量化(需允许安装第三方库)。
实现思路
- 安装兼容Python2的pyroute2版本:
pip install pyroute2==0.7.2 - 使用
IPRoute类获取网卡的地址属性,通过IFA_F_DYNAMIC标志判断地址是否由DHCP动态分配。
Python2示例代码
from pyroute2 import IPRoute def is_dhcp_with_pyroute2(interface_name): ip = IPRoute() # 获取目标网卡的索引 try: idx = ip.link_lookup(ifname=interface_name)[0] except IndexError: return False # 网卡不存在 # 获取网卡的地址信息 addrs = ip.get_addr(index=idx) for addr in addrs: # 检查地址是否带有动态分配标志(IFA_F_DYNAMIC对应位为12) if addr.get_attr('IFA_FLAGS') & (1 << 12): return True return False # 调用示例 print(is_dhcp_with_pyroute2('eth0'))
内容的提问来源于stack exchange,提问作者Paiusco
相关产品推荐
相关产品推荐

