您的位置:首页 >c++如何读取Linux系统的/proc/mounts获取磁盘挂载点【实战】
发布于2026-05-03 阅读(0)
扫一扫,手机访问
在Linux系统里,想查看当前有哪些磁盘挂上了,去哪儿找最直接?答案就是 /proc/mounts 这个文件。它本质上是一个由内核动态生成的文本快照,格式固定,内容一目了然。用C++的标准文件流去读它,其实比调用那些封装好的库函数更轻巧、也更可控,还能顺便绕开对 的依赖以及随之而来的内存管理细节。
新手常犯的一个错误是,自己动手解析时,总担心字段里会不会有空格。其实大可不必过度紧张。没错,第4列的挂载选项(比如 relatime,strictatime)确实可能包含逗号,但它本身不会包含空格。而第3列的文件系统类型,以及最后的第5、6列,都永远是单个词。所以,放心地用空格去切分前4个字段,这个操作是安全的。

为什么推荐标准库的这套组合拳?因为 /proc/mounts 每行的字段之间,是用多个连续空格分隔的,而不是制表符。更关键的是,第4列内部用逗号分隔。如果自己写循环去切分,很容易掉进坑里。而标准流里的 >> 提取操作符有个天然优势:它会自动跳过所有多余的空白字符,正好完美适配这种格式。
来看一个核心代码片段:
std::ifstream mounts("/proc/mounts");
std::string line;
while (std::getline(mounts, line)) {
if (line.empty() || line[0] == '#') continue;
std::istringstream iss(line);
std::string dev, mp, fstype, opts;
if (iss >> dev >> mp >> fstype >> opts) {
// 此时 mp 就是挂载点路径,如 "/home" 或 "/"
std::cout << "Mount point: " << mp << "\n";
}
}
这里有几个细节值得展开说说:
strtok:它会破坏原始字符串,而且对处理多个连续空格的情况并不鲁棒。 在某些旧版本的glibc上性能可能不尽如人意。opts 字段,比如检查里面是否包含 noexec 选项,再用一个 std::stringstream 按逗号分割一次就行了。读 /proc/mounts 本身不需要特殊权限,普通用户就能看。但这里有个至关重要的概念:你看到的内容,取决于你的进程站在哪个“观察点”上,也就是所谓的 mount namespace。
这意味着什么呢?如果你在Docker容器里运行这段代码,默认情况下,你只能看到容器自己这个小世界里的挂载点(比如 /proc, /dev/pts),而看不到宿主机上挂载的 /home 或 /data 目录。这是Linux容器实现隔离的基础机制之一。
/proc 文件系统(不过一般不建议这么做)。那么,什么时候才需要考虑使用 getmntent() 这类C库函数呢?主要是在你需要更明确的语义,或者要获取更底层字段的时候。比如,你想过滤出所有 ext4 或 nfs 类型的文件系统,或者需要用到 mnt_freq、mnt_passno 这些字段,那么 getmntent() 提供的结构体会更清晰。
不过,使用它也得留神:返回的结构体里字段是裸指针,要注意生命周期管理。而且,在musl libc这样的环境下,其行为可能和glibc略有差异。
getmntent() 必须记得配对使用 setmntent() 和 endmntent(),否则可能会有文件句柄泄漏的风险。getmntent("/proc/mounts", "r") 可以直接读,你不需要在代码里硬编码这个路径字符串。std::ifstream 的方案完全没问题。两者在性能上几乎没有实质差别,只是代码风格的选择而已。最后,分享一个实战中极易被忽略的排查思路:当你发现读取的挂载信息不符合预期时,别一头扎进解析逻辑里死磕。先跳出代码,确认一下当前进程所处的挂载命名空间。在systemd service、Podman容器或者chroot环境里,结果很可能天差地别。一个简单的命令 ls /proc/self/ns/mnt,就能帮你快速确认自己的“视角”是否和宿主机一致。很多时候,问题就出在这个上下文上。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9