1. 概述

我们在 Linux 中挂载设备的过程中使用了mount和umount命令。但是,还有另一种挂载点类型,称为绑定挂载。在本教程中,我们将了解绑定挂载是什么,我们还将看到一些何时可以使用它的示例。

2. mount介绍

首先,让我们快速回顾一下mount命令。在 Linux 系统中,我们可以使用mount命令将设备挂载到目录中。这允许我们访问设备的文件系统。让我们在/mnt/usb上挂载一个由设备/dev/sdc1表示的 U 盘,然后列出其内容:

$ mkdir /mnt/usb
$ mount /dev/sdc1 /mnt/usb
$ ls /mnt/usb
appendix.pdf pictures/

我们可以看到我们刚刚挂载的 U 盘中有一个文件和一个文件夹。现在,我们可以使用findmnt –real列出所有已安装的设备:

$ findmnt --real
TARGET               SOURCE                   FSTYPE      OPTIONS
/                    /dev/sda2                ext4        rw,relatime
├─/home              /dev/sdb1                ext4        rw,relatime
├─/mnt/usb           /dev/sdc1                vfat        rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro
└─/boot/efi          /dev/sda1                vfat        rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro

如我们所见,系统上安装了四个设备,包括我们的 U 盘。每个设备都有一个目标目录,我们可以从中访问设备的文件系统。最后,我们可以卸载 U 盘:

$ umount /dev/sdc1

3.绑定挂载

正如我们在上一节中看到的,我们通常在一个目录中挂载一个设备。但是,我们也可以将一个目录挂载到另一个目录上。我们通过使用带有–bind参数的mount命令来做到这一点。我们可以将绑定挂载视为别名。例如,当我们在/tmp/bar上绑定挂载目录/tmp/foo时,两者将引用相同的内容。我们可以从/tmp/bar访问/tmp/foo 中的文件,反之亦然。我们可以使用任何目录作为绑定挂载源。如果源目录是设备的挂载点,则整个设备将绑定挂载到目标目录上。如果相反,源是设备的子目录,则设备将从该子目录开始绑定安装。当我们使用–bind参数时,源目录内的挂载点不会重新挂载。因此,如果我们想绑定挂载目录和该目录内的所有子挂载,我们必须改用–rbind参数。进行绑定挂载后,我们将无法访问目标目录中的原始内容。当我们挂载设备时也会发生同样的情况。让我们创建一个目录/tmp/foo,其中包含一些文件:

$ mkdir /tmp/foo
$ touch /tmp/foo/bind_mount_example
$ touch /tmp/foo/baeldung

现在,让我们创建一个/tmp/bar目录并将我们的/tmp/foo目录绑定到它:

$ mkdir /tmp/bar
$ mount --bind /tmp/foo /tmp/bar

现在,让我们看看两个文件夹中的内容:

$ ls -l /tmp/foo
total 0
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 baeldung
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 bind_mount_example
$ ls -l /tmp/bar
total 0
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 baeldung
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 bind_mount_example

我们可以看到两个文件夹具有相同的内容。让我们在/tmp/bar 中创建一个新文件,我们将看到内容也可以从/tmp/foo访问

$ echo "new file" > /tmp/bar/new_file
$ cat /tmp/foo/new_file 
new file

我们可以使用findmnt –real列出所有挂载点,包括绑定挂载:

$ findmnt --real
TARGET               SOURCE                   FSTYPE      OPTIONS
/                    /dev/sda2                ext4        rw,relatime
├─/home              /dev/sdb1                ext4        rw,relatime
├─/boot/efi          /dev/sda1                vfat        rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro
└─/tmp/bar           /dev/sda2[/tmp/foo]      ext4        rw,relatime

最后,让我们卸载/tmp/bar

$ umount /tmp/bar

4. 用例

在本节中,我们将看到两个使用绑定挂载时有用的示例。一个为我们提供了一种访问被挂载点隐藏的文件的方法。另一个在使用chroot环境时很有用,它允许我们访问它之外的文件。

4.1. 访问挂载点隐藏的文件

当我们在目录上挂载设备时,该目录的先前内容将被挂载点隐藏。因此,我们无法通过传统方式访问原始内容。但是,我们从上一节中了解到,当我们使用–bind参数时,mount不会绑定源目录中的子挂载。因此,我们可以使用此功能来访问隐藏文件。假设我们有/mnt/usb目录并且我们还没有安装任何 USB 记忆棒。让我们在上面写一些文件:

$ echo baeldung > /mnt/usb/hidden_file_example
$ ls /mnt/usb
hidden_file_example

然后,让我们挂载 U 盘,我们会看到hidden_​​file_example文件不再列出:

$ mount /dev/sdc1 /mnt/usb
$ ls /mnt/usb
appendix.pdf pictures/

所以现在,我们可以使用绑定安装来访问hidden_​​file_example文件。我们将首先创建/tmp/oldmnt目录,然后让我们将/mnt绑定安装到我们的新目录上:

$ mkdir /tmp/oldmnt
$ mount --bind /mnt /tmp/oldmnt

然后,我们可以在/tmp/oldmnt/usb 中看到原始的/mnt/usb内容:

$ ls /tmp/oldmnt/usb
hidden_file_example
$ cat /tmp/oldmnt/usb/hidden_file_example 
baeldung

我们可以注意到,在执行绑定挂载时,我们使用/mnt作为源目录。这是因为–bind参数只忽略子挂载。如果我们使用/mnt/usb,我们会在/tmp/oldmnt 中绑定安装 USB 记忆棒。最后,让我们卸载两个挂载点,/mnt/usb/tmp/oldmnt

$ umount /mnt/usb /tmp/oldmnt

4.2. 在chroot环境之外访问文件

何时使用绑定挂载的另一个示例是在chroot环境中挂载目录。chroot是一个为进程提供有限隔离的程序。使用chroot,我们可以在执行程序时设置根目录。例如,我们可以使用chroot在根目录/home/apache 下运行httpd。这将有效地使/home/apache作为该进程的根目录/。因此,例如,目录/home/apache/www将变为/www。这样,httpd进程将无法访问外部的任何文件/home/apache现在,在chroot环境中执行的进程如何访问它之外的文件?例如,进程可能需要访问来自/lib64 的库和来自/bin 的二进制文件。为了解决这个问题,我们可以使用绑定挂载使这些目录可以从chroot目录访问。让我们准备一个目录/home/chroot来使用chroot命令。首先,让我们创建目录/home/chroot,里面有两个目录,binlib64

$ mkdir /home/chroot
$ mkdir /home/chroot/bin
$ mkdir /home/chroot/lib64

然后,让我们将挂载/bin绑定到/home/chroot/bin并将/lib64绑定到/home/chroot/lib64

$ mount --bind /bin /home/chroot/bin
$ mount --bind /lib64 /home/chroot/lib64

最后,我们可以使用chroot将根目录更改为/home/chroot

$ chroot /home/chroot

现在,我们有了以/home/chroot为根目录的shell 。让我们使用ls列出根目录的内容:

$ ls -l / 
total 16
drwxr-xr-x 2 0 0  4096 Oct 29 21:47 bin
drwxr-xr-x 8 0 0 12288 Oct 29 17:02 lib64
$ ls -l /bin/bash
-rwxr-xr-x 1 0 0 1218032 May  5 16:37 /bin/bash
$ ls -l /lib64/libc-*.so   
-rwxr-xr-x 1 0 0 2173576 Aug 17 20:03 /lib64/libc-2.33.so

如我们所见,我们在chroot环境中,只能访问/bin/lib64。此外,我们可以列出其中的文件。

5. 结论

在本文中,我们首先简要介绍了mount命令。然后,我们了解了绑定挂载以及如何使用它们。最后,我们看到了两个何时使用绑定挂载很有用的示例。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐