如何在Linux下通过C程序检测USB设备是否挂载及识别/dev/sda
在Linux下用C程序检测USB设备
下面提供几种实用的实现方式,适配不同场景需求:
方法1:读取sysfs虚拟文件系统
Linux的sysfs会暴露所有硬件设备的详细信息,USB块设备可通过/sys/block/目录下的设备节点识别。每个块设备目录下的device符号链接会指向其所属的父设备路径,若路径包含usb则说明是USB设备。
示例代码:
#include <stdio.h> #include <dirent.h> #include <string.h> #include <unistd.h> #define SYS_BLOCK_PATH "/sys/block/" int is_usb_device(const char *dev_name) { char path[256]; char resolved_path[256]; snprintf(path, sizeof(path), "%s%s/device", SYS_BLOCK_PATH, dev_name); // 解析符号链接 if (readlink(path, resolved_path, sizeof(resolved_path)-1) == -1) { return 0; } resolved_path[sizeof(resolved_path)-1] = '\0'; // 检查路径中是否包含usb关键字 return strstr(resolved_path, "usb") != NULL; } int main() { DIR *dir = opendir(SYS_BLOCK_PATH); if (!dir) { perror("opendir failed"); return 1; } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // 跳过.和..目录 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } // 检查是否为USB设备 if (is_usb_device(entry->d_name)) { printf("USB块设备:/dev/%s\n", entry->d_name); } } closedir(dir); return 0; }
编译运行:gcc usb_detect_sysfs.c -o usb_detect && ./usb_detect
方法2:使用libudev库(推荐)
libudev是Linux官方提供的设备管理库,能精准、高效地枚举和过滤设备,稳定性优于解析文件或命令输出。
首先安装依赖:sudo apt install libudev-dev(Debian/Ubuntu系)
示例代码:
#include <stdio.h> #include <libudev.h> int main() { struct udev *udev = udev_new(); if (!udev) { perror("udev_new failed"); return 1; } // 创建枚举器,过滤块设备 struct udev_enumerate *enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "block"); udev_enumerate_scan_devices(enumerate); // 遍历设备列表 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); struct udev_list_entry *entry; udev_list_entry_foreach(entry, devices) { const char *path = udev_list_entry_get_name(entry); struct udev_device *dev = udev_device_new_from_syspath(udev, path); // 获取设备的传输类型(usb、ata等) const char *tran = udev_device_get_property_value(dev, "ID_BUS"); if (tran && strcmp(tran, "usb") == 0) { // 获取设备节点名(如sda) const char *dev_node = udev_device_get_devnode(dev); printf("USB块设备:%s\n", dev_node); } udev_device_unref(dev); } udev_enumerate_unref(enumerate); udev_unref(udev); return 0; }
编译运行:gcc usb_detect_udev.c -o usb_detect -ludev && ./usb_detect
方法3:解析lsblk命令输出
如果不想依赖额外库,可直接调用lsblk命令并解析其输出。推荐使用-o NAME,TRAN参数过滤关键信息,简化解析逻辑。
示例代码:
#include <stdio.h> #include <string.h> int main() { // 执行lsblk命令,只输出设备名和传输类型 FILE *fp = popen("lsblk -n -o NAME,TRAN", "r"); if (!fp) { perror("popen failed"); return 1; } char line[128]; while (fgets(line, sizeof(line), fp) != NULL) { char dev_name[32], tran[32]; // 拆分每行内容 if (sscanf(line, "%s %s", dev_name, tran) == 2) { if (strcmp(tran, "usb") == 0) { printf("USB块设备:/dev/%s\n", dev_name); } } } pclose(fp); return 0; }
编译运行:gcc usb_detect_lsblk.c -o usb_detect && ./usb_detect
内容的提问来源于stack exchange,提问作者Rajesh D
相关产品推荐
相关产品推荐

