直接读取 /dev/disk/by-uuid/ 是最简单可靠的方式,其文件名即为小写带连字符的 UUID 字符串,无需解析命令或调用 libblkid;若需查指定设备的文件系统级 UUID 并校验有效性,则应使用 libblkid。

直接读取 /dev/disk/by-uuid/ 目录是最简单可靠的方式
Linux 内核在挂载时会自动为每个块设备生成 UUID 符号链接,存放在 /dev/disk/by-uuid/ 下。只要系统已识别该分区(哪怕未挂载),这个目录里就有对应链接。C++ 不需要调用 libblkid 或解析 lsblk 输出,直接 opendir() + readdir() 就能拿到全部 UUID 列表。
注意:该目录下文件名即 UUID(全小写、带连字符),指向的路径如 /dev/sda1 是设备节点。你需要的是文件名本身,不是目标路径。
- 确保程序有读取该目录权限(通常所有用户可读)
- UUID 是字符串,不要尝试用
strtoul等转数字 - 符号链接目标可能跨设备,
readlink()返回的是相对路径(如../../sda1),建议用realpath()解析成绝对路径再处理
用 libblkid 获取指定设备的 UUID 更精准
当你要查某一个设备(比如 /dev/sdb2)的 UUID,且需确认其文件系统类型或校验是否有效时,libblkid 是标准方案。它比解析 /proc/partitions 或 udevadm 更轻量,也比 fork+exec blkid 命令更可控。
关键步骤是调用 blkid_new_probe_from_filename(),然后 blkid_do_safeprobe(),最后用 blkid_lookup_tag_value() 提取 "UUID"。
立即学习“C++免费学习笔记(深入)”;
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 编译需链接
-lblkid(Ubuntu/Debian 上装libblkid-dev) - probe 对象必须显式释放:
blkid_free_probe(),否则内存泄漏 - 如果设备无文件系统(如空分区、LVM PV),
blkid_do_safeprobe()可能返回 -2(BLKID_PROBE_NONE),此时 UUID 字段为空,不能假设失败就是错误
避免误用 getmntent() 查 UUID
/etc/fstab 和 /proc/mounts 里的 UUID=xxx 是挂载选项,不是实时磁盘属性。很多分区根本没写进 fstab,或者用了 LABEL、设备路径等其它标识方式;更关键的是,getmntent() 只返回已挂载项 —— 它完全无法告诉你一块未挂载的 SSD 分区 UUID 是什么。
典型误判场景:U 盘拔出后,/proc/mounts 里消失,但 /dev/disk/by-uuid/ 仍保留链接(直到下次 udev 事件刷新),此时后者才反映真实设备存在性。
- 不要把
getmntent()当作发现设备的手段 - 即使你只关心已挂载分区,也优先从
/dev/disk/by-uuid/反查链接目标是否在/proc/mounts中,而不是反过来 -
findmnt --output=UUID,SOURCE是 shell 场景下的更好替代,但 C++ 里没必要为此 fork
注意大小写和格式一致性
Linux 内核生成的 UUID 全部小写、含 4 个连字符(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),但某些旧工具或手动写入的 fstab 可能用大写或省略连字符。C++ 程序若要做匹配(比如根据 UUID 查设备),必须统一转换为小写并补全连字符格式,否则 strcmp() 会失败。
示例:读到的 "A1B2C3D4-E5F6-7890-GHIJ-KLMNOPQRSTUVWX" 是无效格式(含大写字母和非法字符),实际不可能出现在 /dev/disk/by-uuid/ 中;但用户输入或配置文件里可能出现,需提前过滤或标准化。
- 用
std::transform(str.begin(), str.end(), str.begin(), ::tolower)统一小写 - 连字符位置固定,可用正则或硬编码检查长度和分隔符位置,避免把 32 位无连字符字符串误认为 UUID
- 真正用于比较的 UUID 字符串应严格满足 RFC 4122 格式(小写、36 字符、4 连字符),别依赖
blkid输出做格式假设
dd 覆盖了前几个扇区(比如重刷 ISO),旧 UUID 就彻底丢失,/dev/disk/by-uuid/ 里对应链接也会消失 —— 这时候任何 C++ 代码都读不到,得先确认设备是否真的含有可识别的文件系统。


















