4.7 Objective 7: Create and Change
Hard and Symbolic Links
A link is a pseudofile that creates a shortcut to
the original file located elsewhere on the filesystem. Links
don't take up very much space, as they don't contain any real
data. While the concept of links may seem a little odd, they
are very useful and can be used for anything from creating a
shortcut, to launching an application, to mirroring the
kernel's source.
There are two types of links used on
Linux:
- Symbolic links
-
A symbolic link is
really a tiny file that contains a pointer to another file.
When Linux opens a symbolic link, it reads the pointer and
then finds the intended file that contains the actual data.
Symbolic links can point to other filesystems, both local
and on networked computers, and they can point to
directories. They are clearly listed as being a link with
the ls -l command by
displaying a special "l" (a lowercase L) in column one, and they have no
file protections of their own (the actual file's permissions
are used instead). Note that if a file with a symbolic link
is deleted, then the symbolic link points to nothing and is
said to be stale.
- Hard links
-
A hard link is not
really a "link" at all, but a copy of another directory
entry. The two directory entries have different names but
point to the same inode and thus to the same actual data,
ownership, permissions, and so on. In fact, if a file with a
hard link is deleted, the link remains, still pointing to
the valid inode. Except for its name, including its location
in the directory hierarchy, the link is indistinguishable
from the original file.
Hard links have two important limitations.
First, because they share inodes, files and any hard links
to them must reside on the same filesystem (inode numbers aren't expected to be
unique across filesystems). Second, hard links cannot point
to directories. However, hard links take no disk space
beyond an additional directory entry.
Symbolic links are used more often than hard
links because they are more versatile and easier to manage,
yet still consume a trivial amount of disk space.
4.7.1 Why Links?
To see an example of
the use of links in practice, consider the directories in
/etc/rc.d: drwxr-xr-x 2 root root 1024 Dec 15 23:05 init.d
-rwxr-xr-x 1 root root 2722 Apr 15 1999 rc
-rwxr-xr-x 1 root root 693 Aug 17 1998 rc.local
-rwxr-xr-x 1 root root 9822 Apr 13 1999 rc.sysinit
drwxr-xr-x 2 root root 1024 Dec 2 09:41 rc0.d
drwxr-xr-x 2 root root 1024 Dec 2 09:41 rc1.d
drwxr-xr-x 2 root root 1024 Dec 24 15:15 rc2.d
drwxr-xr-x 2 root root 1024 Dec 24 15:15 rc3.d
drwxr-xr-x 2 root root 1024 Dec 24 15:16 rc4.d
drwxr-xr-x 2 root root 1024 Dec 24 15:16 rc5.d
drwxr-xr-x 2 root root 1024 Dec 14 23:37 rc6.d
Inside init.d
are scripts to start and stop many of the services on your
system, such as httpd, cron, and syslog. Some of these files are to be
executed with a start argument,
while others are run with a stop argument, depending upon the
runlevel of your system. To determine just which files
are run and what argument they receive, a scheme of additional
directories has been devised. These directories are named
rc0.d through rc6.d, one for each runlevel (see Chapter
5 Boot, Initialization, Shutdown,
and Runlevels (Topic 2.6), for a complete description
of this scheme). Each of the runlevel-specific directories
contains several links, each with a name that helps determine
the configuration of services on your system. For example,
rc3.d contains the following links, among many others:
S30syslog -> ../init.d/syslog
S40crond -> ../init.d/crond
S85httpd -> ../init.d/httpd
All of these links point back to the scripts
in init.d as indicated by the arrows (->)
after the script name. If these links were copies of the
scripts, editing would be required for all of the
runlevel-specific versions of the same script just to make a
single change. Instead, links allow us to:
-
Make changes to the original file once.
References to the links will yield the updated contents as
long as the filename doesn't change.
-
Avoid wasting disk space by having multiple
copies of the same file in different places for
"convenience."
As another example, consider the directory
for the kernel source, /usr/src/linux : linux -> linux-2.2.10
linux-2.2.10
Makefiles and other
automated tools can refer to /usr/src/linux, but in reality, they reference
/usr/src/linux-2.2.10. If a new kernel is added, say
Version 2.2.14, its source would be placed into an
appropriately named directory and the linux link would
be reset, as follows: linux -> linux-2.2.14
linux-2.2.10
linux-2.2.14
Now the appropriate directory can be selected
simply by changing the link. No files need to be moved or
deleted. Once created, links are normal directory entries,
which may be copied, renamed, deleted, and backed up.
Symbolic and hard links are created with the
ln command.
Syntaxln [options] file link
ln [options] files directory
Description
Create links between
files. In the first form, a new link is created to
point to file, which must already exist. In the second
form, links are created in directory for all
files specified.
Frequently used options
- -f
-
Overwrite (force) existing links, or
existing files in the destination directory.
- -i
-
Prompt interactively before overwriting
destination files.
- -s
-
Create a symbolic link rather than a hard
link; this is the default.
Example 1
Note that the Bourne shell sh on a Linux system is a symbolic
link to bash: $ ls -l /bin/bash /bin/sh
/bin/bash
/bin/sh -> bash
Example 2
Create a file named myfile, a symbolic
link to that file named myslink, and a hard link to
that file named myhlink, then examine them: $ touch myfile
$ ln -s myfile myslink
$ ln myfile myhlink
$ ls -l my*
-rw-r--r-- 2 jdoe jdoe 0 Jan 3 13:21 myfile
-rw-r--r-- 2 jdoe jdoe 0 Jan 3 13:21 myhlink
lrwxrwxrwx 1 jdoe jdoe 6 Jan 3 13:21 myslink -> myfile
Using the stat
command on my* demonstrates
that they all ultimately reference the same inode (the inode
numbers are the same) and indicates the number of links to the
file (two links, one symbolic and one hard): # stat my*
File: "myfile"
Size: 0 Filetype: Regular File
Mode: (0644/-rw-r--r--) Uid: (0/ root) Gid: (0/ root)
Device: 8,6 Inode: 30 Links: 2
Access: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Modify: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Change: Mon Jan 3 14:33:25 2000(00000.00:05:44)
File: "myhlink"
Size: 0 Filetype: Regular File
Mode: (0644/-rw-r--r--) Uid: (0/ root) Gid: (0/ root)
Device: 8,6 Inode: 30 Links: 2
Access: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Modify: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Change: Mon Jan 3 14:33:25 2000(00000.00:05:44)
File: "myslink"
Size: 0 Filetype: Regular File
Mode: (0644/-rw-r--r--) Uid: (0/ root) Gid: (0/ root)
Device: 8,6 Inode: 30 Links: 2
Access: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Modify: Mon Jan 3 14:33:04 2000(00000.00:06:05)
Change: Mon Jan 3 14:33:25 2000(00000.00:05:44)
However, the symbolic link has an inode of
its own, which is displayed using the -i option to ls: # ls -li my*
30 -rw-r--r-- 2 root root 0 Jan 3 14:33 myfile
30 -rw-r--r-- 2 root root 0 Jan 3 14:33 myhlink
41 lrwxrwxrwx 1 root root 6 Jan 3 14:33 myslink -> myfile
Here you can see that the directory entries
for myfile and myhlink both point to inode 30,
while the directory entry for myslink points to inode
41. That inode contains the symbolic link to myfile.
As another example, consider the two
filesystems in Figure
4-4. The root partition on /dev/sda1 holds a file
intended as an example bash
startup file, located in /etc/bashrc_user. On the same
filesystem, the root user has elected to use
/etc/bashrc_user. Not wanting to maintain both files
individually, root has created
a hard link, /root/.bashrc, to the example file. Both
of the directory entries, /etc/bashrc_user and
/root/.bashrc, point to the same text data in the same
file, described by the same inode, on /dev/sda1. User
jdoe has also elected to link to the example file.
However, since his home directory is located in /home
on /dev/sda9, jdoe cannot use a hard link to the
file on /dev/sda1. Instead, he created a symbolic link,
/home/jdoe/.bashrc, which points to a small file on
/dev/sda9. This contains the pointer to directory entry
/etc/bashrc_user, which finally points at the
text. The result for root and jdoe is
identical, though the two styles of links implement the
reference in completely different ways.
4.7.1.1 Preserving links
Programs such as
tar and cp contain options that control
whether symbolic links are followed during operation. In the
case of a tar backup, this may
be important if you have multiple links to large files,
because you would get many redundant backups of the same data.
When a symbolic link is encountered with
cp , the contents
of the file to which the link points are copied unless the
-d option is specified. This
"no dereference" operator causes cp to copy the links themselves
instead. For example, consider a directory dir1
containing a symbolic link, which is recursively copied to
other directories with and without the -d option: # ls -l dir1
total 13
lrwxrwxrwx 1 root root 19 Jan 4 02:43 file1 -> /file1
-rw-r--r-- 1 root root 10240 Dec 12 17:12 file2
# cp -r dir1 dir2
# ls -l dir2
total 3117
-rw-r--r-- 1 root root 3164160 Jan 4 02:43 file1
-rw-r--r-- 1 root root 10240 Jan 4 02:43 file2
# cp -rd dir1 dir3
# ls -l dir3
total 13
lrwxrwxrwx 1 root root 19 Jan 4 02:43 file1 -> /file1
-rw-r--r-- 1 root root 10240 Jan 4 02:43 file2
Directory dir2 has a copy of the
entire file1, which is large, probably wasting disk
space. Directory dir3, created with cp -rd, is the same as dir1
(including the symbolic link) and takes very little space.
4.7.1.2 Finding links to a
file
Finding the file pointed to by a symbolic
link is simple. The ls -l
command displays a convenient pointer notation, indicating
just where links are pointing: lrwxrwxrwx 1 root root 19 Jan 4 02:43 file1 -> /file1
Going the other way and finding symbolic
links to a file is less obvious but is still relatively easy.
The -lname option to the
find utility locates them for
you by searching for symbolic links containing the original
filename. Here, the entire local filesystem is searched for
myfile, turning up three symbolic links: # find / -lname myfile
/home/world/rootsfile
/home/finance/hisfile
/root/myslink
Remember that symbolic links could be
anywhere, including being located on a remote system (if
you're sharing files), so you may not be able to locate them
all. (SeeSection
3.1 for additional information on the find command).
Since hard links aren't really links, but
duplicate directory entries, you can locate them by searching
directory entries for the inode, which is identical in all the
links. Unlike symbolic links, you are guaranteed to find all
of the links since hard links cannot cross filesystem
boundaries. First, identify the inode you're interested in, as
well as the filesystem that contains the links: # df file1
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/sda9 1981000 451115 1427473 24% /home
# ls -i file
90469 file1
Here, file1 is on the /home
filesystem, and its inode number is 90469. Next, find is used with the -inum option to locate all instances
of inode 90469: # find /home -inum 90469
/home/world/file1
/home/finance/file1
/home/jdoe/private/.myfile1
This example turns up three links to
file1, including one that user jdoe appears to
be hiding!
You should be prepared to identify the
differences between hard and symbolic links, when each
is used, and their limitations.
|
|