最可靠方式是遍历/dev/disk/by-uuid/目录解析符号链接:文件名即uuid,目标路径经标准化后得设备节点;该方案零依赖、无需特权、实时准确,且比libblkid轻量、比blkid命令稳健。

Linux下C++读取分区UUID的可靠方式是解析/dev/disk/by-uuid/符号链接
直接调用libblkid虽底层准确,但需链接额外库、处理上下文生命周期,且在容器或精简系统中常不可用;而/proc/partitions或lsblk输出解析又依赖外部命令和文本格式稳定性。最轻量、可移植、无需特权的方式,是遍历/dev/disk/by-uuid/目录下的符号链接——每个文件名即UUID,指向的实际设备路径(如/dev/sda1)可反向映射。
注意:/dev/disk/by-uuid/由udev维护,只要系统启用udev(几乎所有现代Linux发行版默认启用),该目录就始终可用且内容实时准确。
示例代码片段(使用C++17 std::filesystem):
#include <filesystem>
#include <string>
#include <iostream><p>for (const auto& entry : std::filesystem::directory_iterator{"/dev/disk/by-uuid/"}) {
if (entry.is_symlink()) {
std::string uuid = entry.path().filename().string();
std::string target = std::filesystem::read_symlink(entry.path()).string();
// target 形如 "../../sda1",需标准化
std::string dev_path = std::filesystem::weakly_canonical("/dev/disk/by-uuid/" + target).string();
std::cout " </p></iostream></string></filesystem>
用readlink()手动解析符号链接更可控,避免std::filesystem::read_symlink()的异常风险
std::filesystem::read_symlink()在目标不存在或权限不足时抛出std::filesystem::filesystem_error,而实际环境中(如chroot、某些容器)符号链接可能指向尚未挂载或不可见的设备节点,导致程序意外中断。
改用POSIX readlink()并手动处理缓冲区更稳妥:
- 分配足够大的缓冲区(
PATH_MAX),避免截断 - 检查返回值是否为正数且小于缓冲区长度
- 用
std::filesystem::path(target).is_absolute()判断是否需拼接/dev/前缀 - 对相对路径(如
../../sda1)调用std::filesystem::weakly_canonical()前先补全基路径
关键片段:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
char buf[PATH_MAX]; ssize_t len = readlink(entry.c_str(), buf, sizeof(buf) - 1); if (len > 0 && len <h3>不要用<code>blkid</code>命令行+<code>popen()</code>,它有三重隐患</h3><p>常见做法是拼接<code>"blkid -o value -s UUID "</code>加设备路径再<code>popen()</code>执行,但实际部署中极易出问题:</p>
-
blkid缓存机制导致刚格式化或挂载的分区UUID不立即可见,需加-c /dev/null禁用缓存 - 不同发行版
blkid版本输出格式不一致(如旧版无-o value,新版默认带引号),解析易错 - 若
PATH未包含/sbin(如某些容器环境),popen()直接失败,且错误难定位
除非明确需要获取文件系统类型(TYPE)、LABEL等其他属性,否则纯UUID场景下,/dev/disk/by-uuid/目录方案零依赖、无外部进程、响应快。
注意/dev/disk/by-uuid/中重复UUID的含义和处理
正常情况下每个UUID唯一对应一个分区,但遇到以下情况会看到多个同名链接:
- LVM逻辑卷:同一LV可能被多个设备节点(如
/dev/mapper/vg-lv和/dev/dm-0)引用,均指向相同UUID - RAID成员盘:若RAID阵列本身有UUID(如mdadm元数据),其成员盘也可能生成独立UUID链接
- 快照或克隆分区:人为复制分区表后未重置UUID,会导致冲突
此时不能简单按UUID去重,而应结合设备路径层级判断:优先保留/dev/sdXN、/dev/nvmeXnYpZ这类物理命名,忽略/dev/dm-或/dev/mapper/路径(除非业务明确需要LVM层面的映射)。
真正容易被忽略的是:UUID字符串本身区分大小写,但Linux内核和大多数工具将其视为不区分大小写;而/dev/disk/by-uuid/目录里的文件名是小写形式(如123e4567-e89b-12d3-a456-426614174000)。硬编码比较时务必统一转小写。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










