You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:15:11