Примечание переводчика: в статье рассматриваются основные принципы работы bind mount, а также примеры его использования для доступа к скрытым файлам и работы с chroot-окружениями.
Команды mount и umount используются для монтирования/размонтирования устройств в Linux. Однако существует и другой тип монтирования, называемый bind mount. В этом материале мы поговорим о том, что это такое, а также рассмотрим несколько примеров применения bind mount.

Пара слов о mount
Сначала вспомним, что делает команда mount. В системах на базе Linux она позволяет примонтировать устройство или директорию. В результате мы получаем доступ к файловой системе устройства.
К примеру, примонтируем USB-накопитель /dev/sdc1 в /mnt/usb и выведем его содержимое:
$ mkdir /mnt/usb $ mount /dev/sdc1 /mnt/usb $ ls /mnt/usb appendix.pdf pictures/
Видно, что на только что смонтированном USB-накопителе есть файл и директория. Вывести информацию обо всех точках монтирования в системе можно с помощью 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
Всего в системе примонтировано четыре устройства, включая USB-накопитель. У каждого устройства есть целевой каталог, из которого можно получить доступ к его файловой системе. Наконец, можно размонтировать USB-накопитель:
$ umount /dev/sdc1
Bind mount
В предыдущем разделе мы монтировали устройство в директорию. Но также можно примонтировать директорию в другую директорию. Для этого команда mount запускается с флагом --bind.
В некотором смысле bind mount создаёт алиас. Например, если примонтировать /tmp/foo в /tmp/bar, обе директории будут ссылаться на одно и то же содержимое. Можно открывать файлы в /tmp/foo из /tmp/bar и наоборот.
В качестве источника для bind mount можно использовать любую директорию. Если исходная директория является точкой монтирования устройства, то все устройство будет примонтировано к директории назначения. Если источник — поддиректория устройства, то будут примонтированы все директории, для которых эта поддиректория является родительской.
При использовании параметра --bind точки монтирования внутри исходной директории не перемонтируются. Чтобы примонтировать их вместе со всеми вложенными точками монтирования, используют флаг --rbind.
После bind-монтирования теряется доступ к содержимому целевой директории. То же самое происходит при монтировании устройств.
Создадим директорию /tmp/foo с несколькими файлами в ней:
$ mkdir /tmp/foo $ touch /tmp/foo/bind_mount_example $ touch /tmp/foo/baeldung
Теперь создадим директорию /tmp/bar и bind-примонтируем к ней директорию /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 можно вывести все точки монтирования, включая те, которые созданы bind mount:
$ 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
Варианты использования
В этом разделе мы рассмотрим два примера с bind mount. В одном bind mount помогает получить доступ к файлам, скрытым точкой монтирования. Другой полезен при работе с chroot-окружениями и открывает доступ к файлам за их пределами.
Доступ к файлам, скрытым точкой монтирования
При монтировании устройства в директорию её содержимое скрывается точкой монтирования. То есть обычным способом получить доступ к нему не получится. Однако, как мы узнали из предыдущего раздела, bind mount не монтирует дочерние точки монтирования из исходной директории. Эту особенность можно использовать для доступа к скрытым файлам.
Предположим, что есть директория /mnt/usb и мы ещё не успели примонтировать в неё USB-устройство. Создадим в ней файл:
$ echo baeldung > /mnt/usb/hidden_file_example $ ls /mnt/usb hidden_file_example
Затем подключим USB-накопитель — файл hidden_file_example больше не виден:
$ mount /dev/sdc1 /mnt/usb $ ls /mnt/usb appendix.pdf pictures/
Получить доступ к нему можно с помощью bind-монтирования. Для этого создадим директорию /tmp/oldmnt, а затем примонтируем в неё /mnt:
$ mkdir /tmp/oldmnt $ mount --bind /mnt /tmp/oldmnt
Исходное содержимое /mnt/usb появится в /tmp/oldmnt/usb:
$ ls /tmp/oldmnt/usb hidden_file_example $ cat /tmp/oldmnt/usb/hidden_file_example baeldung
Обратите внимание, что мы выполнили bind mount директории /mnt. Как уже говорилось, --bind игнорирует только дочерние точки монтирования. Если бы мы примонтировали /mnt/usb, в /tmp/oldmnt появилось бы содержимое USB-накопителя. В завершение давайте отмонтируем /mnt/usb и /tmp/oldmnt:
$ umount /mnt/usb /tmp/oldmnt
Доступ к файлам за пределами chroot-окружения
Другой пример использования bind mount — монтирование директорий в chroot-окружениях. chroot обеспечивает ограниченную изоляцию процессов, устанавливая корневую директорию для процесса. Например, можно сделать так, чтобы httpd считал /home/apache корневой директорией /. В этом случае /home/apache/www превратится в /www, при этом у httpd не будет доступа к файлам за пределами /home/apache.
Возникает вопрос: как процессу, который работает в chroot-окружении, получить доступ к файлам за его пределами? Например, ему могут понадобиться библиотеки из /lib64 и исполняемые файлы из /bin. Bind mount решает эту проблему — с его помощью к этим директориям можно получить доступ из chroot-окружения. В качестве примера создадим директорию /home/chroot и две дочерние директории, bin и lib64, в ней:
$ mkdir /home/chroot $ mkdir /home/chroot/bin $ mkdir /home/chroot/lib64
Теперь bind-примонтируем /bin к /home/chroot/bin, а /lib64 — к /home/chroot/lib64:
$ mount --bind /bin /home/chroot/bin $ mount --bind /lib64 /home/chroot/lib64
Наконец, изменим корневую директорию на /home/chroot:
$ chroot /home/chroot
Получим оболочку с /home/chroot в качестве корневой директории. Выведем её содержимое:
$ 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 и их содержимому.
Заключение
Bind mount — фундаментальный и гибкий инструмент в арсенале Linux, позволяющий эффективно управлять доступом к файлам и директориям. В этой статье мы познакомились с ними и рассказали о том, как его можно использовать. Наконец, мы рассмотрели два примера того, когда bind mount может пригодиться.
P. S.
Читайте также в нашем блоге:
