You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RHEL上用Python判断网卡是否使用DHCP(不依赖Shell命令)

可行解决方案

方案1:通过NetworkManager的DBus接口获取实时状态

RHEL默认使用NetworkManager管理网络,它通过DBus暴露了所有网络设备的实时配置与状态信息,无需调用外部命令,纯Python即可直接访问,结果能准确反映当前生效的网络配置。

实现思路

  1. 用Python的dbus模块连接到系统级的NetworkManager DBus服务。
  2. 遍历所有网络设备,匹配目标网卡名称。
  3. 获取该网卡的活跃连接,读取连接的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。

实现思路

  1. 针对不同网络管理工具,对应不同的租约文件路径:
    • NetworkManager:/var/lib/NetworkManager/dhclient-<interface>.lease
    • 传统dhclient:/var/lib/dhclient/dhclient-{interface}.leases
    • systemd-networkd:/run/systemd/netif/leases/<数字索引>-<interface>
  2. 检查目标路径下的文件是否存在,可选验证租约是否未过期。

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通信库,可直接从内核获取网络设备的实时配置,无需依赖外部命令,结果精准且轻量化(需允许安装第三方库)。

实现思路

  1. 安装兼容Python2的pyroute2版本:pip install pyroute2==0.7.2
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:40:34