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 ?
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 (
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.
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
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/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
In addition to the other answers. The system does not allow hard link to directory:
# ln mydir mpoint ln: `mydir': hard link not allowed for directory
The mount let you make hard link-like ie two or more names for same one inode:
# mount -B mydir/ mpoint/ # ls -d -i * 807175 mpoint/ 807175 mydir/
(One can find it helps for snapshot-backup with old version of rsync.)
Also, note that this mount is not complete:
# mount -B -oro mydir/ mpoint/ mount: warning: mpoint/ seems to be mounted read-write. # mount | grep mpoint /root/learn/mydir on /root/learn/mpoint type none (rw,bind)
So, the mount is still read and write even if I asked for the option ro (read only).