There comes a time when it's handy to have a file exist in more than one place on your file system; however, its not practical to copy it to each place. Aside from the added disk space, you would quickly lose track of which file was the latest copy. Under certain circumstances you could use CVS or RCS to maintain the several copies, but that would still require updating each copy every time a change was committed.
A symbolic link accomplishes the same thing as multiple copies of a file, without requiring any actual copies of the file. The link merely places an additional name for the file in another part of the of the filesystem. No file copying is involved. Two different names both reference the same data.
There are two kinds of links: hard links and symbolic links. A hard link is indistinguishable from the original file and must exist on the same filesystem partition as the original file. It truely becomes an alternate name for the file. Deleting a hard link to a file does not delete the file until the last link is deleted. Since there is no difference between the original filename and the hard links, it makes no difference which filename remains; deleting the original filename doesn't delete the file as long as one link remains to provide access to the data.
When you try to link between two partitions or link to a directory, you have to use a symbolic link. A symbolic link behaves similarly to a hyper-link like you would find on a web page. It places an alternate name for the file that points to the location of the file being linked to. Much like web links, if you delete the destination or original file, the link becomes a broken link.
Symbolic links are also easy to spot. Using ls -l, you can see which files are symbolic links and where they point to.
> ls -l /
-rwxrwxr-t 1 root admin 9 Nov 28 18:49 mach -> /mach.sym
-r--r--r-- 1 root admin 705904 Nov 28 18:49 mach.sym
-rw-r--r-- 1 root wheel 3728752 Nov 5 23:01 mach_kernel
drwxr-xr-x 3 chrisc admin 102 Nov 13 22:33 opt
drwxr-xr-x 6 root wheel 204 Nov 28 18:49 private
drwxr-xr-x 60 root wheel 2040 Nov 28 18:43 sbin
lrwxrwxr-t 1 root admin 11 Nov 28 18:49 tmp -> private/tmp
drwxr-xr-x 12 root wheel 408 Jul 14 00:21 usr
lrwxrwxr-t 1 root admin 11 Nov 28 18:49 var -> private/var
You will notice that the above list of directories shows three symbolic links, or symlinks. The file mach is points to mach.sym and the directories /tmp and /var are linked to directories in the /private directory. If I deleted any of the symlinks, the destination files would remain untouched, the link would merely go away. So, deleting mach would not delete mach.sym; however, deleting mach.sym would make the symlink pointing to it stop working.
The big benefit of using symlink is that you can move the destination file around and then adjust the symlinks that point to it. A practical use of this would be to move a large file or directory from a small partition to a larger partition and then replace it with a symlink that points to the original file.
For example, my /tmp directory is located on my root directory which is very small and I keep having problems with programs requiring more space than /tmp has available. I have two options, first I could repartition the disk and give more disk space to the /tmp directory. Or, I could move the /tmp directory to a partition that had lots of room and replace it with a symlink. If I didn't replace it with a symlink then any program that relied on the location of /tmp would quit working. However, the symlink tells them the new location of /tmp without making them go look for it.
Links are created with the ln(1) command. The syntax for ln(1) can be a bit confusing at first. It takes the file that exists as the first argument and the second parameter is the location of the link to be created. By default ln(1) creates hard links, you have to use the -s flag to create a symbolic link.
So to move the /tmp directory, you would use the following commands. (You will need to be root to do this.)
# mv /tmp /usr/local/tmp
# ln -s /usr/local/tmp /tmp
>ls -l /tmp
lrwxrwxr-t 1 root admin 11 Nov 28 18:49 tmp -> /usr/local/tmp
As you can see, /tmp has been moved to /usr/local/tmp and been replaced with a symlink. If I cd to that /tmp I will find myself in /usr/local/tmp instead.
> cd /tmp
> pwd
/usr/local/tmp
> cd ..
> pwd
/usr/local
If you find yourself constantly changing to a directory that is very deep, a symlink shortcut could be just what you need. It is possible create a shell alias to do that for you, but a symlink shortcut will allow your scripts to use it as well as any programs that might rely upon it, where your shell alias won't.
The options to ln(1) are as follows:
- -f
- Unlink any already existing file, permitting the link to occur.
- -h
- If the target_file or target_dir is a symbolic link, do not follow it. This is most useful with the -f option, to replace a symlink which may point to a directory.
- -n
- Same as -h, for compatibility with other ln implementations.
- -s
- Create a symbolic link.
To adjust a link use the -f and -h options together.
# mv /usr/local/tmp /usr/share/tmp
# ln -sfh /usr/share/tmp /tmp
An ls -l /tmp will reveal the newly adjusted location.
> ls -l /tmp
lrwxrwxr-t 1 root admin 9 Nov 28 18:49 mach -> /mach.sym
One word of caution however; you don't want to link a file to a symbolic link. It will let you do it, because it doesn't resolve where the file points to when the link it created. So its possible do to this:
lrwxr-xr-x 1 chrisc staff 7 Dec 2 21:46 file -> oldfile
lrwxr-xr-x 1 chrisc staff 4 Dec 2 21:46 newfile -> file
lrwxr-xr-x 1 chrisc staff 7 Dec 2 21:46 oldfile -> newfile
However, when you try to write to any of the actual files, it will give you an error.
Error: file: Too many levels of symbolic links.
Conclusion
We can now recognize symlinks with ls(1) and create them with ln(1). We have also learned how to adjust them without rm(1) to delete them. Links are very powerful when you need to re-arrange your filesystem without disturbing programs already installed. It can also make management easier by creating shortcuts to files or directories that are located deep in the filesystem.