当前位置: 首页 > news >正文

Linux系统用户的专属福利:除了lsusb,如何利用usb.ids文件离线查询所有USB设备VID/PID信息?

Linux系统深度实践:离线高效查询USB设备VID/PID的完整指南

当你身处没有网络连接的机房,或是调试嵌入式设备时,突然需要确认一个USB设备的厂商信息,该怎么办?对于Linux系统用户来说,答案就藏在系统深处的一个小文件中——usb.ids。这个不起眼的文本文件,实际上是Linux系统管理USB设备的秘密武器。

1. 理解USB设备标识体系

每个USB设备都带有两个关键标识符:VID(Vendor ID)和PID(Product ID)。这两个16位数字组合,构成了USB设备的"身份证":

  • VID:由USB-IF(USB Implementers Forum)分配给设备制造商
  • PID:由制造商自行定义,标识具体产品型号

在Linux系统中,这些标识符的映射关系被存储在一个结构化的文本数据库中。不同于需要联网查询的在线服务,本地usb.ids文件提供了随时可用的离线查询能力,特别适合以下场景:

  • 无网络环境的服务器机房
  • 嵌入式设备开发调试
  • 自动化脚本中的设备识别
  • 批量处理多个USB设备信息

2. 定位系统中的usb.ids文件

不同Linux发行版中,usb.ids文件可能存放在以下几个位置:

文件路径常见发行版备注
/usr/share/misc/usb.idsDebian/Ubuntu, Fedora最普遍的位置
/var/lib/usbutils/usb.ids较新的系统由usbutils包维护
/usr/share/hwdata/usb.ids某些Red Hat系系统替代位置

要确认你的系统中是否存在该文件,可以执行:

find /usr /var -name "usb.ids" 2>/dev/null

如果系统中没有找到该文件,可能需要安装usbutils软件包:

# Debian/Ubuntu sudo apt install usbutils # RHEL/CentOS sudo yum install usbutils

3. 解析usb.ids文件结构

usb.ids文件采用层级化的文本格式,主要包含三部分内容:

  1. 厂商列表:以VID开头,后接厂商名称
  2. 产品列表:在厂商条目下,以PID开头,后接产品名称
  3. 设备类信息:定义USB设备类、子类和协议代码

典型条目示例:

1234 Example Manufacturer 5678 Sample Product A 9abc Sample Product B

理解这个结构后,我们可以利用各种文本处理工具从中提取所需信息。

4. 实战查询技巧

4.1 基础查询方法

使用grep命令进行简单查询:

# 查询特定VID对应的厂商 grep -i "^1234" /usr/share/misc/usb.ids # 查询特定VID和PID组合 grep -A1 -i "^1234" /usr/share/misc/usb.ids | grep -i "5678"

4.2 高级查询脚本

对于更复杂的查询需求,可以创建可重用的脚本:

#!/bin/bash USBIDS_FILE="/usr/share/misc/usb.ids" if [ $# -lt 1 ]; then echo "Usage: $0 <VID> [PID]" exit 1 fi VID=$(echo "$1" | tr '[:lower:]' '[:upper:]') PID=$2 if [ -z "$PID" ]; then # 只查询VID grep -m1 -i "^${VID}" "$USBIDS_FILE" else # 查询VID和PID组合 PID=$(echo "$PID" | tr '[:lower:]' '[:upper:]') awk -v vid="$VID" -v pid="$PID" ' BEGIN {found_vid=0} $1 == vid {found_vid=1; print; next} found_vid && /^\t/ && $1 == pid {print; exit} found_vid && /^\t/ && $1 != pid {next} found_vid && !/^\t/ {exit} ' "$USBIDS_FILE" fi

将此脚本保存为usbquery并赋予执行权限后,可以方便地查询:

./usbquery 093A ./usbquery 093A 2510

4.3 批量处理多个设备

当需要处理多个USB设备信息时,可以结合lsusb和脚本处理:

lsusb | awk '{print $6}' | while IFS=: read vid pid; do echo "Device $vid:$pid:" ./usbquery "$vid" "$pid" done

5. 维护与更新本地数据库

虽然离线查询很方便,但usb.ids文件需要定期更新以包含最新的设备信息。

5.1 手动更新方法

# 下载最新usb.ids文件 sudo wget http://www.linux-usb.org/usb.ids -O /usr/share/misc/usb.ids # 或者使用curl sudo curl -o /usr/share/misc/usb.ids http://www.linux-usb.org/usb.ids

5.2 自动化更新

创建定期更新的cron任务:

# 每月1号凌晨3点更新 0 3 1 * * root /usr/bin/curl -s -o /usr/share/misc/usb.ids http://www.linux-usb.org/usb.ids

5.3 验证文件完整性

更新后建议检查文件有效性:

head -n 10 /usr/share/misc/usb.ids # 应该看到类似内容: # # List of USB ID's # # # # Maintained by Stephen J. Gowdy <linux.usb.ids@gmail.com> # # If you have any new entries, please submit them via # # http://www.linux-usb.org/usb-ids.html

6. 系统集成与应用实例

6.1 在Python中解析usb.ids

def get_usb_info(vid, pid=None): with open('/usr/share/misc/usb.ids', 'r', encoding='iso-8859-1') as f: current_vid = None for line in f: line = line.strip() if not line or line.startswith('#'): continue if not line.startswith('\t'): # VID行 parts = line.split(maxsplit=1) if len(parts) == 2 and parts[0].lower() == vid.lower(): current_vid = parts[1] if pid is None: return current_vid elif current_vid and pid: # PID行 parts = line.strip().split(maxsplit=1) if len(parts) == 2 and parts[0].lower() == pid.lower(): return f"{current_vid} - {parts[1]}" return None

6.2 与udev规则结合

创建自定义udev规则,自动识别特定设备:

# /etc/udev/rules.d/99-usb-custom.rules ACTION=="add", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="1234", ENV{ID_MODEL_ID}=="5678", SYMLINK+="my_device"

6.3 嵌入式系统中的应用考虑

在资源受限的嵌入式系统中:

  1. 可以只保留需要的VID/PID条目,减小文件大小
  2. 将文件放入只读文件系统节省空间
  3. 使用压缩版本(如usb.ids.gz)节省存储
# 创建精简版usb.ids grep -e "^1234" -e "^abcd" /usr/share/misc/usb.ids > minimal.usb.ids

7. 性能优化与高级技巧

对于频繁查询的应用场景,可以考虑以下优化方案:

7.1 数据库转换

将文本文件转换为SQLite数据库提高查询效率:

#!/bin/bash INPUT="/usr/share/misc/usb.ids" OUTPUT="/var/lib/usb_ids.db" # 创建SQLite数据库 sqlite3 "$OUTPUT" <<EOF CREATE TABLE vendors (vid TEXT PRIMARY KEY, name TEXT); CREATE TABLE products (vid TEXT, pid TEXT, name TEXT, PRIMARY KEY (vid, pid)); BEGIN; EOF # 解析并导入数据 awk -v DB="$OUTPUT" ' /^#/ {next} /^[^\t]/ && NF>=2 { vid = $1 name = substr($0, index($0,$2)) print "INSERT INTO vendors VALUES (\"" vid "\", \"" name "\");" >> DB } /^\t/ && NF>=2 { pid = $1 name = substr($0, index($0,$2)) print "INSERT INTO products VALUES (\"" vid "\", \"" pid "\", \"" name "\");" >> DB } ' "$INPUT" # 提交事务并创建索引 sqlite3 "$OUTPUT" <<EOF COMMIT; CREATE INDEX idx_products_vid ON products (vid); CREATE INDEX idx_products_pid ON products (pid); EOF

7.2 内存缓存方案

对于需要极低延迟的应用,可以将数据加载到内存中:

import sqlite3 from collections import defaultdict class USBCache: def __init__(self, db_path='/var/lib/usb_ids.db'): self.conn = sqlite3.connect(db_path) self.vendor_cache = {} self.product_cache = defaultdict(dict) self._load_data() def _load_data(self): # 加载厂商数据 for vid, name in self.conn.execute("SELECT vid, name FROM vendors"): self.vendor_cache[vid.lower()] = name # 加载产品数据 for vid, pid, name in self.conn.execute("SELECT vid, pid, name FROM products"): self.product_cache[vid.lower()][pid.lower()] = name def get_vendor(self, vid): return self.vendor_cache.get(vid.lower()) def get_product(self, vid, pid): return self.product_cache.get(vid.lower(), {}).get(pid.lower())

7.3 与系统监控工具集成

结合lsusbusb.ids创建增强型监控脚本:

#!/bin/bash # 增强版lsusb,显示完整厂商和设备信息 lsusb | while read -r line; do bus=$(echo "$line" | awk '{print $2}') dev=$(echo "$line" | awk '{print $4}' | tr -d ':') vid_pid=$(echo "$line" | awk '{print $6}') vid=${vid_pid%:*} pid=${vid_pid#*:} vendor=$(./usbquery "$vid") product=$(./usbquery "$vid" "$pid") printf "Bus %s Device %s: ID %s %s\n" "$bus" "$dev" "$vid_pid" "$product" done
http://www.jsqmd.com/news/726386/

相关文章:

  • OSWorld:真实操作系统环境下的智能体基准测试平台部署与评测指南
  • 手机号逆向查询QQ号:3分钟快速找回遗忘账号的完整方案
  • Docker 27沙箱隔离增强:金融级容器上线前必做的7项合规审计项(等保2.0+GDPR双标覆盖)
  • 别再瞎调了!Spartan-6 FPGA的IOB供电(VCCAUX/VCCO)与电平标准配置避坑指南
  • 在 openclaw 项目中集成 taotoken 实现多模型 agent 工作流
  • 如何将微信聊天记录转化为个人数字资产:WeChatMsg数据分析工具深度解析
  • 电堆/电池包气密性检测哪家好?2026年靠谱的气密性检漏仪厂家盘点与推荐:广州雷克检测领衔 - 栗子测评
  • 免费实现专业级物理渲染:Mitsuba-Blender插件完整使用指南
  • 3分钟搞定顽固窗口!WindowResizer:你的Windows窗口调整终极神器
  • 告别ORB!用PyTorch复现Deep Homography Estimation,手把手教你训练自己的单应性网络
  • 揭秘低查重AI教材编写方法,借助工具轻松搞定教材创作
  • 企业上SaaS系统为什么用不起来?问题往往不在软件,而在业务没人推进
  • #2026口碑最佳广州市智能体开发横评:七款广州市代理商实力单品精准测评 - 十大品牌榜
  • 在客服工单系统中集成大模型API实现智能回复
  • 2026年论文写完AI率仍然偏高攻略:反复检测不过的核心解决方案
  • PlatformIO的platformio.ini还能这么玩?一个项目搞定STM32多下载器与条件编译
  • 3个核心功能+5种场景配置:QTTabBar终极指南让Windows文件管理效率翻倍
  • 从游戏数据到数字记忆:YaeAchievement如何重构你的原神成就体验
  • PSpice仿真避坑指南:AC Sweep设置里这几个参数没搞懂,仿真结果可能全错
  • 保姆级教程:用Docker Compose一键部署OpenProject 12,并配置NPM反代和HTTPS访问
  • 11.【Verilog】Verilog 跨时钟域传输:慢到快
  • Illustrator脚本自动化:高效智能设计工作流优化最佳实践
  • 2026年论文第一章绪论AI率偏高攻略:引言和研究背景部分降AI处理指南
  • STM32 CAN总线通讯实验
  • 精馏塔哪个厂家质量好?国产排名+优质厂家深度测评 - 品牌推荐大师
  • 7天从零到一:PyQt6桌面应用开发实战指南
  • 构建内容生成流水线时如何借助Taotoken灵活切换不同大模型
  • 如何用这款神器,3分钟看懂你的《英雄联盟》比赛回放?
  • 为 Hermes Agent 配置 Taotoken 作为自定义模型提供商
  • WindowResizer终极指南:如何轻松突破Windows窗口大小限制