杰瑞科技汇

Python如何安装ethtool?

ethtool 本身是一个用 C 语言编写的 Linux 命令行工具,用于查询和设置网卡参数,Python 并没有一个叫做 ethtool 的官方标准库。

Python如何安装ethtool?-图1
(图片来源网络,侵删)

我们有几种方法可以在 Python 中实现类似 ethtool 的功能,其中最常用和推荐的是通过 subprocess 模块调用系统自带的 ethtool 命令

下面我将分步介绍如何实现这一点。


通过 subprocess 调用系统 ethtool (推荐)

这是最直接、最可靠的方法,因为它直接利用了系统已经成熟稳定的 ethtool 工具,无需额外安装复杂的 Python 库。

步骤 1:确保系统已安装 ethtool

你的 Linux 系统上必须安装 ethtool 命令本身,如果没安装,可以使用包管理器进行安装。

Python如何安装ethtool?-图2
(图片来源网络,侵删)

在 Debian / Ubuntu / Mint 上:

sudo apt update
sudo apt install ethtool

在 CentOS / RHEL / Fedora / Rocky Linux 上:

sudo yum install ethtool
# 或者使用 dnf (新版系统)
sudo dnf install ethtool

在 Arch Linux 上:

sudo pacman -S ethtool

安装完成后,你可以在终端中直接使用 ethtool 命令来测试,例如查看网卡 eth0 的信息:

Python如何安装ethtool?-图3
(图片来源网络,侵删)
ethtool eth0

步骤 2:在 Python 中使用 subprocess 调用

subprocess 模块是 Python 的标准库,无需额外安装,我们可以用它来执行 shell 命令并获取输出。

下面是一个完整的 Python 示例,它定义了一个函数来获取指定网卡的详细信息。

import subprocess
import shlex
def get_eth_info(interface_name: str):
    """
    使用 ethtool 命令获取指定网卡的详细信息。
    Args:
        interface_name (str): 网卡名称,'eth0', 'ens33'。
    Returns:
        dict: 包含网卡信息的字典,如果出错则返回 None。
    """
    try:
        # 使用 shlex.quote 来安全地处理接口名称,防止命令注入
        cmd = shlex.quote(f"ethtool {interface_name}")
        # 执行命令并捕获输出
        # text=True 会自动将输出解码为字符串
        # encoding='utf-8' 指定编码
        # errors='ignore' 忽略解码错误
        result = subprocess.run(cmd, shell=True, check=True, 
                                capture_output=True, text=True, 
                                encoding='utf-8', errors='ignore')
        # 解析输出
        info = {}
        for line in result.stdout.splitlines():
            if ':' in line:
                key, value = line.split(':', 1)
                info[key.strip()] = value.strip()
        return info
    except subprocess.CalledProcessError as e:
        # ethtool 命令执行失败 (网卡不存在)
        print(f"执行命令 '{e.cmd}' 失败。")
        print(f"错误码: {e.returncode}")
        print(f"错误信息: {e.stderr}")
        return None
    except Exception as e:
        # 其他可能的异常
        print(f"发生未知错误: {e}")
        return None
# --- 使用示例 ---
if __name__ == "__main__":
    # 替换成你自己的网卡名称
    interface = "eth0" 
    print(f"正在获取网卡 {interface} 的信息...")
    eth_details = get_eth_info(interface)
    if eth_details:
        print("\n--- 网卡信息 ---")
        # 打印一些关键信息
        print(f"接口: {eth_details.get('Settings', 'N/A')}")
        print(f"速度: {eth_details.get('Speed', 'N/A')}")
        print(f"双工模式: {eth_details.get('Duplex', 'N/A')}")
        print(f"自动协商: {eth_details.get('Auto-negotiation', 'N/A')}")
        print(f"MAC地址: {eth_details.get('Permanent address', 'N/A')}")
        print(f"当前地址: {eth_details.get('Current address', 'N/A')}")
        print(f"支持的端口: {eth_details.get('Supported ports', 'N/A')}")
        print(f"支持的速率: {eth_details.get('Supported link modes', 'N/A')}")
        # 你也可以打印所有信息
        # for key, value in eth_details.items():
        #     print(f"{key}: {value}")

代码解释:

  1. import subprocess: 导入 Python 的标准库 subprocess。
  2. shlex.quote(): 这是一个非常重要的安全函数,它会转义字符串中的特殊字符,防止用户输入恶意内容导致命令注入攻击。
  3. subprocess.run(...): 这是执行命令的核心函数。
    • shell=True: 通过 shell 执行命令,可以解析通配符和变量。
    • check=True: 如果命令返回非零退出码(表示失败),则会抛出 CalledProcessError 异常。
    • capture_output=True: 捕获标准输出和标准错误。
    • text=True: 将捕获的输出作为文本字符串返回,而不是字节。
  4. 异常处理: 我们捕获 CalledProcessError 来处理 ethtool 命令执行失败的情况(例如网卡名错误)。
  5. 解析输出: ethtool 的输出是 "Key: Value" 格式的文本,我们按行分割,然后按冒号分割,将其存入一个字典中,方便后续使用。

使用纯 Python 的第三方库 (如 pyethtool)

如果你不想依赖系统命令,或者需要更底层的、跨平台的实现(尽管 ethtool 本身是 Linux 特有的),可以考虑使用第三方库。

注意: pyethtool 是一个纯 Python 实现,它通过解析 /proc/sys 文件系统来获取信息,或者使用 ctypes 调用 ethtool 的 C 库,它可能无法提供 ethtool 命令的所有功能,尤其是在设置参数方面。

步骤 1:安装 pyethtool

使用 pip 进行安装:

pip install pyethtool

步骤 2:在 Python 中使用 pyethtool

import pyethtool
# --- 使用示例 ---
if __name__ == "__main__":
    # 替换成你自己的网卡名称
    interface = "eth0"
    try:
        # 获取网卡属性
        attrs = pyethtool.get_attrs(interface)
        print(f"\n--- 使用 pyethtool 获取 {interface} 的信息 ---")
        # pyethtool 返回的是一个包含多个属性对象的列表
        # 我们可以遍历它来找到我们关心的信息
        for attr in attrs:
            # 获取速度 (SPEED) 和双工模式 (DUPLEX)
            if attr.name == 'SPEED':
                print(f"速度: {attr.value} Mbps")
            elif attr.name == 'DUPLEX':
                print(f"双工模式: {attr.value}")
            elif attr.name == 'LINK':
                print(f"链路状态: {'已连接' if attr.value else '未连接'}")
            elif attr.name == 'AUTONEG':
                print(f"自动协商: {'开启' if attr.value else '关闭'}")
    except IOError as e:
        # 如果网卡不存在或无法访问
        print(f"无法获取网卡 {interface} 的信息: {e}")

pyethtool 的优缺点:

  • 优点:
    • 纯 Python 实现,不直接依赖外部命令(但依赖内核接口)。
    • 代码更“Pythonic”,返回结构化数据。
  • 缺点:
    • 功能可能不完整,特别是 ethtool 的“设置”功能(如 ethtool -s)。
    • 依赖内核 /proc/sys 接口的稳定性。
    • 社区支持和更新频率可能不如 subprocess 方案稳定。

总结与对比

特性 方法一: subprocess 方法二: pyethtool
依赖 系统需安装 ethtool 命令 仅需 Python 环境 (pip install)
功能完整性 极高,等同于 ethtool 命令的所有功能 有限,主要查询功能,设置功能可能不全
性能 调用外部进程,有轻微开销 纯 Python,理论上更快,但差异不大
安全性 需正确使用 shlex.quote 防止注入 较高,无外部命令注入风险
代码复杂度 需要手动解析文本输出 返回结构化数据,使用更直接
推荐度 ★★★★★ (强烈推荐) ★★★☆☆ (适用于特定场景或轻量级需求)

最终建议:

对于绝大多数在 Python 中使用 ethtool 的场景,使用 subprocess 调用系统 ethtool 是最佳选择,它最可靠、功能最全,并且是处理此类系统级任务的“标准”Pythonic 方式,只有在无法安装系统 ethtool 或有非常轻量级查询需求时,才考虑使用 pyethtool 这样的第三方库。

分享:
扫描分享到社交APP
上一篇
下一篇