本文介绍如何使用Python在树莓派上可靠检测已插入的USB存储设备,并获取其挂载路径以进行文件读写操作,重点解决pyudev无法直接获取挂载点的问题。
本文介绍如何使用python在树莓派上可靠检测已插入的usb存储设备,并获取其挂载点以进行文件读写操作,重点解决`pyudev`无法直接获取挂载点的问题。
在树莓派上通过Python检测和访问USB存储设备,常被误认为只需监听内核事件即可完成全部流程。实际上,pyudev能精准捕获硬件级信息(如厂商、型号、总线类型、设备节点 /dev/sda),但挂载点(如 /media/pi/CCCOMA_X64FRE_EN-GB_DV9)属于用户空间的文件系统管理范畴,不由内核直接暴露,因此不会出现在 device.properties 中。
要完整实现“检测 → 定位 → 访问”,需分两步协同处理:
✅ 第一步:用 pyudev 检测 USB 块设备并提取设备节点
修正原代码逻辑(避免遍历所有属性、增强健壮性):
import pyudev
def find_usb_block_devices():
context = pyudev.Context()
usb_disks = []
for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
# 仅筛选 USB 总线设备,且排除虚拟设备(如 loop、ram)
if device.get('ID_BUS') == 'usb' and not device.get('ID_VENDOR_ID') is None:
dev_node = device.device_node # e.g., '/dev/sda'
model = device.get('ID_MODEL', 'Unknown').replace('_', ' ')
vendor = device.get('ID_VENDOR_FROM_DATABASE', device.get('ID_VENDOR', 'Unknown'))
usb_disks.append({
'node': dev_node,
'vendor': vendor,
'model': model,
'bus': device.get('ID_BUS')
})
return usb_disks
# 示例调用
for disk in find_usb_block_devices():
print(f"USB Disk: {disk['vendor']} {disk['model']} → {disk['node']}")✅ 第二步:通过 findmnt 查询对应分区的挂载点
USB 设备通常在 /dev/sdX1(首个分区)挂载。我们需先获取分区设备节点(如 /dev/sda1),再查询其挂载路径:
立即学习“Python免费学习笔记(深入)”;
import subprocess
import os
def get_mount_point(device_node):
"""根据 /dev/sdX 获取其首个已挂载分区的挂载点,返回字符串或 None"""
if not device_node:
return None
# 构造分区名(假设为第一个主分区)
partition = f"{device_node}1"
try:
# 使用 findmnt 安全获取挂载目标(-no 表示仅输出 TARGET 字段,-l 表示只显示一行)
result = subprocess.check_output(
['findmnt', '-no', 'TARGET', partition],
stderr=subprocess.STDOUT,
text=True
).strip()
if result and os.path.ismount(result):
return result
except (subprocess.CalledProcessError, FileNotFoundError):
pass # 未挂载或命令不存在(极罕见)
return None
# 结合使用示例
for disk in find_usb_block_devices():
mount_path = get_mount_point(disk['node'])
if mount_path:
print(f"✅ Mounted at: {mount_path}")
# 现在可安全执行文件操作,例如:
# import shutil; shutil.copy('/path/to/file', f'{mount_path}/backup/')
else:
print(f"⚠️ Not mounted: {disk['node']} (check if auto-mount is enabled)")⚠️ 关键注意事项
- 自动挂载依赖桌面环境:Raspberry Pi OS(带桌面版)默认启用 udisks2 实现自动挂载;若使用 Lite 版或无 GUI 环境,需手动挂载(sudo mount /dev/sda1 /mnt/usb)或配置 autofs。
- 权限问题:普通用户需在 plugdev 组中才能访问 /media/xxx;运行 sudo usermod -aG plugdev pi 并重启生效。
- 设备热插拔稳定性:建议添加 time.sleep(1) 或轮询重试机制,避免因 udev 事件与挂载延迟不同步导致 findmnt 查不到结果。
- 替代方案:如需更轻量级方案,可直接解析 /proc/mounts 或 mount 命令输出,但 findmnt 更可靠(专为结构化查询设计)。
掌握这一组合方案后,你即可在树莓派上构建稳定、可部署的USB数据同步脚本——从识别物理设备到读写用户数据,全程可控、可调试、可扩展。


















