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设备这里会显示usbPATH列:设备的绝对路径(比如/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
相关产品推荐
相关产品推荐

