在Linux系统中检测USB设备的插拔事件,可以通过多种方法实现,以下将详细介绍几种常见的方法:
使用 `lsusb` 命令
原理
lsusb
是一个用于列出当前连接的USB设备的命令,通过定期运行该命令并比较输出结果,可以检测USB设备的插入和拔出。
示例代码(Python)
import subprocess def list_usb_devices(): result = subprocess.run(['lsusb'], capture_output=True, text=True) return result.stdout def detect_usb_change(previous_output): current_output = list_usb_devices() if current_output != previous_output: print("USB device changed!") return current_output if __name__ == "__main__": previous_output = "" while True: current_output = detect_usb_change(previous_output) previous_output = current_output
使用 `udev` 库
原理
udev
是Linux系统中用于动态管理设备节点的守护进程,通过监听udev
事件,可以实时检测USB设备的插拔。
示例代码(C)
#include <libudev.h> #include <stdio.h> int main() { struct udev *udev = udev_new(); if (!udev) { fprintf(stderr, "Cannot create udev context "); return 1; } struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", NULL); udev_monitor_enable_receiving(mon); while (1) { struct udev_device *dev = udev_monitor_receive_device(mon); if (dev) { const char *action = udev_device_get_action(dev); if (strcmp(action, "add") == 0 || strcmp(action, "remove") == 0) { printf("USB device %s ", action); } udev_device_unref(dev); } } udev_unref(udev); return 0; }
使用 `Netlink` 机制
原理
Netlink
是一种内核与用户空间的通信机制,适用于捕获内核事件(例如USB设备的插拔)。
示例代码(C)
#include <linux/netlink.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #define UEVENT_BUFFER_SIZE 2048 int main() { int CppLive = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); if (CppLive < 0) { perror("socket"); return -1; } struct sockaddr_nl client; memset(&client, 0, sizeof(client)); client.nl_family = AF_NETLINK; client.nl_pid = getpid(); client.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; bind(CppLive, (struct sockaddr *)&client, sizeof(client)); while (1) { char buf[UEVENT_BUFFER_SIZE] = { 0 }; int rcvlen = recv(CppLive, &buf, sizeof(buf), 0); if (rcvlen > 0) { printf("%s ", buf); } } close(CppLive); return 0; }
4. 使用Qt
框架中的QProcess
类
原理
利用Qt
提供的QProcess
类来启动外部进程,并通过解析其输出来检测USB设备的插拔,这种方法不需要了解USB接口的底层细节。
示例代码(C++)
#include <QCoreApplication> #include <QProcess> #include <QStringList> #include <QByteArray> #include <QDebug> int usbCount(const QString &vendor) { QProcess process; QStringList args; if (!vendor.isEmpty()) { args << "-d" << vendor; } process.start("lsusb", args); process.waitForFinished(); QString result = QString(process.readAllStandardOutput()); QStringList outputList = result.split(" "); return outputList.count(); //返回可能包含一行空字符行,但是不影响检测结果 } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int usbCnt = -1; bool usbChanged = true; QString argd = "096e:0303"; // USB设备的venderID和productID,这个是可以预知的,当然不输入也可以 do { int usbCnt_new = usbCount(argd); if (usbCnt == usbCnt_new) { usbChanged = false; } else { usbChanged = true; } usbCnt = usbCnt_new; if (usbChanged) { // yes! QThread::sleep(2000); // 休眠2秒以避免频繁检测 } } while (true); return a.exec(); }
以下是对这几种方法的详细对比:
方法 | 优点 | 缺点 | 适用场景 |
lsusb | 简单易用,无需额外依赖 | 需要定期轮询,资源消耗较大 | 简单的USB设备监控 |
udev | 实时性强,适合系统级应用 | 需要了解udev 库的使用 | 嵌入式系统、复杂应用 |
Netlink | 高效,适合高性能需求 | 实现复杂,需要处理内核消息 | 高性能需求的应用 |
Qt + QProcess | 跨平台,集成方便 | 依赖于Qt框架 | Qt应用程序中集成USB监控 |
Linux下检测USB设备的插拔有多种方法,可以根据具体需求选择合适的方案,无论是简单的脚本还是复杂的系统级应用,都有相应的解决方案。
以上就是关于“linux 检测usb插拔”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!
本文来源于互联网,如若侵权,请联系管理员删除,本文链接:https://www.9969.net/85857.html