Linux mount --bind 与 --rbind 的子挂载差异
来源:17golang原创
时间:2026-11-01 10:24:15 138浏览 收藏
把目录映射到另一个位置时,mount --bind 和 mount --rbind 的关键差别不是“是否递归复制普通文件”,而是“是否把源目录下已经存在的子挂载一并挂过去”。普通 bind 只附着指定的挂载点;rbind 会递归处理这棵挂载树。
这篇用一个带子挂载的目录模型说明两条命令的边界,并给出检查和清理方式。示例只用于解释结构,实际执行前应确认源目录、目标目录和当前挂载命名空间都属于你的维护范围。
官方资料:https://docs.kernel.org/filesystems/sharedsubtree.html
先分清目录树与挂载树
假设源路径是 /srv/project,它下面有普通目录 config,还有一个独立挂载在 data 上。目录树看起来只有一个父目录和两个子目录,但挂载树实际上多了一层“挂载在 data 上的文件系统”。
--bind 复制的是指定的挂载点关系:它让目标路径看到 /srv/project 这个整体,但不会自动把 /srv/project/data 的独立子挂载再复制一份。--rbind 的 r 表示 recursive,会沿着源挂载树处理子挂载,所以目标下的 data 仍然对应一个子挂载。

用最小项目模型对比两条命令
为了把差异固定下来,可以把源目录和两个目标目录看成一个小型挂载实验的资源边界。下面的命令是可复制的示例,中文注释说明每组命令的目的;它不会在本文写作过程中被执行。
# 准备源目录和两个目标目录,避免目标路径已经是挂载点 sudo mkdir -p /srv/project/config /srv/project/data sudo mkdir -p /mnt/project-bind /mnt/project-rbind # 普通 bind:只建立源挂载点到目标挂载点的映射 sudo mount --bind /srv/project /mnt/project-bind # 递归 bind:把源目录下面已有的子挂载也纳入目标树 sudo mount --rbind /srv/project /mnt/project-rbind # 用树状视图查看两个目标各自包含哪些挂载 findmnt -R /mnt/project-bind findmnt -R /mnt/project-rbind
如果 data 只是一个普通目录,两条命令看起来可能接近;只有当 data 本身是独立挂载点时,--rbind 才会体现出递归差异。这也是排查“映射过去后子目录内容不对”的第一处判断。
不要把 cp -a 或目录遍历和 rbind 混为一谈。rbind 不复制文件内容,它建立的是挂载关系;源文件系统的变化和挂载属性仍受当前挂载命名空间与传播规则影响。
用 findmnt 看清子挂载和传播属性
只执行 ls 很难判断某个目录是普通目录还是独立挂载。findmnt -R 更适合看目标路径下的挂载树,重点观察目标本身、data 子路径以及它们的文件系统类型和挂载选项。
# 只查看目标树,避免把整台机器的挂载混在一起 findmnt -R /mnt/project-bind findmnt -R /mnt/project-rbind # 查看挂载传播状态,排查 shared、slave 或 private 边界 findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS,PROPAGATION \ /mnt/project-bind /mnt/project-rbind
检查时可以按三点读结果:第一,目标根是否出现;第二,源目录中的独立子挂载是否在 rbind 目标下出现;第三,PROPAGATION 是否显示了 shared、slave 或 private。第三点属于传播语义,不由“r”这个字母单独决定。

什么时候选 bind,什么时候选 rbind
只需要把一个目录作为单一入口暴露给另一个路径时,优先考虑 --bind。例如把一个配置目录或单个数据目录映射到服务工作目录,排除不希望跟随的子挂载更容易控制。
需要保留完整挂载树时再用 --rbind,常见于把一棵系统目录树放进另一个根目录、准备隔离环境或映射包含多个独立文件系统的目录。使用前要确认源树中没有不应暴露的挂载点,因为递归范围比普通 bind 大。
如果环境还涉及跨命名空间的挂载传播,不要仅靠 --rbind 推断行为。内核文档把 bind/rbind 与 shared、slave、private、unbindable 状态分开描述;需要隔离时,应明确检查并设置传播属性,而不是把递归复制当成传播控制。
清理时别漏掉递归目标
普通 bind 目标通常可以直接卸载;rbind 目标可能包含多个子挂载,清理时应先确认目标树,再递归卸载目标。示例中的 umount -R 是清理目标树的表达方式,实际环境还要结合发行版的 util-linux 版本和是否存在繁忙进程。
# 先确认递归目标下有哪些挂载,避免误卸载相邻资源 findmnt -R /mnt/project-rbind # 递归卸载 rbind 目标及其子挂载 sudo umount -R /mnt/project-rbind # 普通 bind 目标没有需要保留的子挂载时再单独卸载 sudo umount /mnt/project-bind
若卸载失败,先看目标是否被进程占用、是否有子挂载仍在树中,以及目标是否处于共享传播关系。不要直接扩大卸载范围;把 findmnt -R 的结果和目标路径对应起来,通常比反复重试更安全。
常见问题
为什么 bind 后看不到源目录里的挂载内容? 如果子路径是独立挂载点,这是普通 bind 的预期边界;需要连同挂载树一起映射时改用 --rbind,并检查目标的递归结果。
rbind 是否会复制文件? 不会。它复制的是挂载关系,不是目录内容;文件仍由对应的文件系统和挂载命名空间提供。
--rbind 能否代替传播属性设置? 不能。递归挂载和 shared/private 等传播状态是两个维度,必须分别检查和配置。
可以把选择记成一句话:只映射一个挂载点用 --bind,需要保留其下独立子挂载时用 --rbind;无论选择哪一种,都先用 findmnt -R 确认范围,再按目标树清理。
-
133 收藏
-
348 收藏
-
448 收藏
-
403 收藏
-
426 收藏
-
277 收藏
-
126 收藏
-
300 收藏
-
198 收藏
-
146 收藏
-
477 收藏
-
296 收藏
-
451 收藏
-
133 收藏
-
349 收藏
-
126 收藏
-
237 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习