What is the difference between ln -s and mount --bind?
I am trying to understand difference between using ln -s
and mount --bind
. In basic scenario I can use both to access one directory from somewhere else. In what scenarios those two will behave differently ?
Solution 1:
They will behave differently in at least two cases:
- In a chroot, if the link target is outside the chroot, the link will be dead. A bind mount will still be accessible.
- Several programs can distinguish between symbolic links and actual directories or files. Few (if any) can distinguish between a directory or file and the one mounted on it. This also extends to symbolic links to something (
A
) which have something else (B
) mounted on them. The link will show the contents of mount target (B
) instead of the original (A
).
Also, you can bind mount a directory or file on an existing directory or file, masking the original contents (rendering the original contents inaccessible unless the original was bind mounted elsewhere). A symbolic link requires that the original be moved or deleted.
Solution 2:
Well, ln -s
creates a symbolic link, whereas mount --bind
creates a mount.
A symbolic link is a special type of file. If you do ln -s /var/target /var/link
, then /var/link
will be a file containing the path "/var/target
" in it. The only difference between a symbolic link and an ordinary file is that when a program tries to perform an operation on a symbolic link, the operation is usually performed on the target instead of the file. So now if you do ls /var/link
, the ls
program will try to get a directory listing for /var/link
, but will actually get a directory listing for /var/target
instead.
Symbolic links are still just files, though. They can be renamed and deleted and all that jazz. Note that you can't create a symbolic link (or an ordinary file, for that matter) called /var/link
if there's already a file called /var/link
; you'd need to get rid of it first.
A mount isn't a file; it's a record that the kernel keeps in memory. If you do mount --bind /var/target /var/mount
, the kernel will record the fact that /var/mount
is now a new name for /var/target
. (I don't know the details; in particular, I don't know if mounting something in a subdirectory of /var/target
will make it show up in /var/mount
as well, or why or why not. Edits to this answer would be appreciated.) So now if you do ls /var/mount
, the same thing will happen as if you did ls /var/target
, because /var/mount
and /var/target
are the same directory.
Mounts aren't files. I don't know what would happen if you tried to rename or delete /var/mount
. Note that you can't mount anything at /var/mount
unless there's already a directory at /var/mount
.
Solution 3:
Additionally, ln -s would survive a reboot; whereas mount --bind would not, unless you edit /etc/fstab to make it persistent.