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

Linux下识别未正确自动挂载USB设备的Python脚本实现

解决USB大容量存储设备与挂载点关联的问题

我明白你现在的痛点——已经能识别出USB大容量存储设备,但没法把它们和实际的挂载点对应起来。下面我给你几个实用的方案,不管是用Linux命令组合配合subprocess解析,还是用Python原生模块,都能搞定这个问题。

方案一:用lsblk + udevadm命令组合(适合subprocess解析)

这两个命令能拿到设备的USB标识信息和挂载点,通过共同的设备路径关联起来,非常适合用Python脚本解析。

步骤1:用lsblk筛选USB块设备

lsblk可以列出系统里的块设备,加上参数后能输出JSON格式(方便Python解析),还能标记出USB传输类型的设备:

lsblk -J -o NAME,MOUNTPOINT,TRAN,PATH
  • -J:输出JSON格式,避免字符串解析的麻烦
  • TRAN列:显示设备的传输类型,USB设备这里会显示usb
  • PATH列:设备的绝对路径(比如/dev/sdb1),用来后续调用udevadm

步骤2:用udevadm获取USB设备的唯一标识

对每个TRAN为usb的设备,用udevadm获取它的USB属性(比如厂商ID、产品ID、序列号),这些信息可以和你用lsusb或PyUSB拿到的信息匹配:

udevadm info --query=property --name=/dev/sdb

输出里的关键属性:

  • ID_VENDOR_ID:厂商ID(和lsusb里的ID一致,比如0781)
  • ID_PRODUCT_ID:产品ID(比如5580)
  • ID_SERIAL_SHORT:设备序列号(唯一标识,比厂商+产品ID更准确)

Python解析示例

把这两个命令结合起来,用subprocess和json模块解析:

import subprocess
import json

# 第一步:获取所有USB块设备的基本信息
lsblk_output = subprocess.run(
    ["lsblk", "-J", "-o", "NAME,MOUNTPOINT,TRAN,PATH"],
    capture_output=True, text=True
)
block_devices = json.loads(lsblk_output.stdout)["blockdevices"]

usb_block_devices = []
for dev in block_devices:
    # 筛选USB传输的设备,包括分区(比如sdb1)
    if dev.get("tran") == "usb":
        usb_block_devices.append(dev)
        # 如果有子分区,也一起加入
        if "children" in dev:
            usb_block_devices.extend(dev["children"])

# 第二步:获取每个USB设备的USB属性并关联挂载点
for dev in usb_block_devices:
    dev_path = dev["path"]
    udev_output = subprocess.run(
        ["udevadm", "info", "--query=property", "--name", dev_path],
        capture_output=True, text=True
    )
    # 解析udev输出的键值对
    udev_props = {}
    for line in udev_output.stdout.splitlines():
        if "=" in line:
            key, value = line.split("=", 1)
            udev_props[key] = value
    
    # 匹配你用PyUSB拿到的设备信息
    vendor_id = udev_props.get("ID_VENDOR_ID")
    product_id = udev_props.get("ID_PRODUCT_ID")
    mount_point = dev.get("mountpoint")
    
    print(f"USB设备 {vendor_id}:{product_id}")
    print(f"挂载点: {mount_point if mount_point else '未挂载'}")
    print("---")

方案二:用Python的pyudev模块(更简洁,无需调用subprocess)

如果不想折腾命令行解析,pyudev这个模块可以直接和系统的udev数据库交互,一次性拿到USB设备的所有属性(包括挂载点和USB标识),代码更简洁易维护。

安装pyudev

pip install pyudev

示例代码

import pyudev
import usb.core
import usb.util

# 第一步:用PyUSB识别所有USB大容量存储设备
usb_storage_devices = []
devices = usb.core.find(find_all=True)
for dev in devices:
    # 大容量存储设备的设备类是8
    if dev.bDeviceClass == 8:
        vendor_id = format(dev.idVendor, '04x')
        product_id = format(dev.idProduct, '04x')
        usb_storage_devices.append((vendor_id, product_id))

# 第二步:用pyudev关联挂载点
context = pyudev.Context()
# 遍历所有块设备分区
for device in context.list_devices(subsystem='block', DEVTYPE='partition'):
    # 判断是否是USB设备
    if device.get('ID_BUS') == 'usb':
        dev_vendor = device.get('ID_VENDOR_ID')
        dev_product = device.get('ID_PRODUCT_ID')
        mount_point = device.get('MOUNTPOINT')
        
        # 和PyUSB识别的设备匹配
        if (dev_vendor, dev_product) in usb_storage_devices:
            print(f"匹配到USB大容量存储设备: {dev_vendor}:{dev_product}")
            print(f"挂载状态: {'已挂载到' + mount_point if mount_point else '未挂载'}")
            print("---")

一些注意事项

  • 序列号的重要性:如果你的场景里有多个同型号的USB设备,建议用ID_SERIAL_SHORT(序列号)来匹配,比厂商+产品ID更准确,避免混淆。
  • 权限问题:部分系统下,普通用户可能无法获取完整的udev属性,建议用sudo运行脚本,或者给当前用户添加udev相关权限。
  • 未挂载设备:上面的代码会标记出未挂载的USB设备,正好符合你“识别未正确自动挂载的USB设备”的需求。

内容的提问来源于stack exchange,提问作者ProgrammingRookie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:04:11