Links
An average computer using Linux has a file system with many hard links
and symbolic links.
To understand links in a file system, you first have to understand what
an inodeinode is.
inodes
======
inode contents
An inode is a data structure that contains metadata about a file. When
the file system stores a new file on the hard disk, it stores not only
the contents (data) of the file, but also extra properties like the name
of the file, the creation date, its permissions, the owner of the file,
and more. All this information (except the name of the file and the
contents of the file) is stored in the inode of the file.
The ls -lls command will display some of the inode contents, as seen
in this screenshot.
root@rhel53 ~# ls -ld /home/project42/
drwxr-xr-x 4 root pro42 4.0K Mar 27 14:29 /home/project42/
inode table
The inode tableinode table contains all of the inodes and is created
when you create the file system (with mkfsmkfs). You can use the
df -idf -i command to see how many inodes are used and free on
mounted file systems.
root@rhel53 ~# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/VolGroup00-LogVol00
4947968 115326 4832642 3% /
/dev/hda1 26104 45 26059 1% /boot
tmpfs 64417 1 64416 1% /dev/shm
/dev/sda1 262144 2207 259937 1% /home/project42
/dev/sdb1 74400 5519 68881 8% /home/project33
/dev/sdb5 0 0 0 - /home/sales
/dev/sdb6 100744 11 100733 1% /home/research
In the df -i screenshot above you can see the inode usage for
several mounted file systems. You don\'t see numbers for /dev/sdb5
because it is a fat file system.
inode number
Each inode has a unique number (the inode number). You can see the
inode numbers with the ls -lils(1) command.
paul@RHELv4u4:~/test$ touch file1
paul@RHELv4u4:~/test$ touch file2
paul@RHELv4u4:~/test$ touch file3
paul@RHELv4u4:~/test$ ls -li
total 12
817266 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file1
817267 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file2
817268 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file3
paul@RHELv4u4:~/test$
These three files were created one after the other and got three
different inodes (the first column). All the information you see with
this ls command resides in the inode, except for the filename (which
is contained in the directory).
inode and file contents
Let\'s put some data in one of the files.
paul@RHELv4u4:~/test$ ls -li
total 16
817266 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file1
817270 -rw-rw-r-- 1 paul paul 92 Feb 5 15:42 file2
817268 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file3
paul@RHELv4u4:~/test$ cat file2
It is winter now and it is very cold.
We do not like the cold, we prefer hot summer nights.
paul@RHELv4u4:~/test$
The data that is displayed by the cat command is not in the inode,
but somewhere else on the disk. The inode contains a pointer to that
data.
about directories
a directory is a table
A directorydirectory is a special kind of file that contains a table
which maps filenames to inodes. Listing our current directory with
ls -alils(1) will display the contents of the directory file.
paul@RHELv4u4:~/test$ ls -ali
total 32
817262 drwxrwxr-x 2 paul paul 4096 Feb 5 15:42 .
800768 drwx------ 16 paul paul 4096 Feb 5 15:42 ..
817266 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file1
817270 -rw-rw-r-- 1 paul paul 92 Feb 5 15:42 file2
817268 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file3
paul@RHELv4u4:~/test$
. and ..
You can see five names, and the mapping to their five inodes. The dot
.. (directory) is a mapping to itself, and the dotdot ....
(directory) is a mapping to the parent directory. The three other names
are mappings to different inodes.
hard links
creating hard links
When we create a hard linkhard link to a file with lnln(1), an extra
entry is added in the directory. A new file name is mapped to an
existing inode.
paul@RHELv4u4:~/test$ ln file2 hardlink_to_file2
paul@RHELv4u4:~/test$ ls -li
total 24
817266 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file1
817270 -rw-rw-r-- 2 paul paul 92 Feb 5 15:42 file2
817268 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file3
817270 -rw-rw-r-- 2 paul paul 92 Feb 5 15:42 hardlink_to_file2
paul@RHELv4u4:~/test$
Both files have the same inode, so they will always have the same permissions and the same owner. Both files will have the same content. Actually, both files are equal now, meaning you can safely remove the original file, the hardlinked file will remain. The inode contains a counter, counting the number of hard links to itself. When the counter drops to zero, then the inode is emptied.
finding hard links
You can use the findfind(1) command to look for files with a certain
inode. The screenshot below shows how to search for all filenames that
point to inode 817270. Remember that an inodeinode number is unique
to its partition.
paul@RHELv4u4:~/test$ find / -inum 817270 2> /dev/null
/home/paul/test/file2
/home/paul/test/hardlink_to_file2
symbolic links
Symbolic links (sometimes called soft linkssoft link) do not link to
inodes, but create a name to name mapping. Symbolic links are created
with ln -sln. As you can see below, the symbolic linksymbolic link
gets an inode of its own.
paul@RHELv4u4:~/test$ ln -s file2 symlink_to_file2
paul@RHELv4u4:~/test$ ls -li
total 32
817273 -rw-rw-r-- 1 paul paul 13 Feb 5 17:06 file1
817270 -rw-rw-r-- 2 paul paul 106 Feb 5 17:04 file2
817268 -rw-rw-r-- 1 paul paul 0 Feb 5 15:38 file3
817270 -rw-rw-r-- 2 paul paul 106 Feb 5 17:04 hardlink_to_file2
817267 lrwxrwxrwx 1 paul paul 5 Feb 5 16:55 symlink_to_file2 -> file2
paul@RHELv4u4:~/test$
Permissions on a symbolic link have no meaning, since the permissions of the target apply. Hard links are limited to their own partition (because they point to an inode), symbolic links can link anywhere (other file systems, even networked).
removing links
Links can be removed with rmrm(1).
paul@laika:~$ touch data.txt
paul@laika:~$ ln -s data.txt sl_data.txt
paul@laika:~$ ln data.txt hl_data.txt
paul@laika:~$ rm sl_data.txt
paul@laika:~$ rm hl_data.txt
practice : links
1. Create two files named winter.txt and summer.txt, put some text in them.
2. Create a hard link to winter.txt named hlwinter.txt.
3. Display the inode numbers of these three files, the hard links should have the same inode.
4. Use the find command to list the two hardlinked files
5. Everything about a file is in the inode, except two things : name them!
6. Create a symbolic link to summer.txt called slsummer.txt.
7. Find all files with inode number 2. What does this information tell you ?
8. Look at the directories /etc/init.d/ /etc/rc2.d/ /etc/rc3.d/ ... do you see the links ?
9. Look in /lib with ls -l...
10. Use find to look in your home directory for regular files that
have more than one hard link (hint: this is identical to all regular
files that do not have exactly one hard link).
solution : links
================
1. Create two files named winter.txt and summer.txt, put some text in them.
echo cold > winter.txt ; echo hot > summer.txt
2. Create a hard link to winter.txt named hlwinter.txt.
ln winter.txt hlwinter.txt
3. Display the inode numbers of these three files, the hard links should have the same inode.
ls -li winter.txt summer.txt hlwinter.txt
4. Use the find command to list the two hardlinked files
find . -inum xyz #replace xyz with the inode number
5. Everything about a file is in the inode, except two things : name them!
The name of the file is in a directory, and the contents is somewhere on the disk.
6. Create a symbolic link to summer.txt called slsummer.txt.
ln -s summer.txt slsummer.txt
7. Find all files with inode number 2. What does this information tell you ?
It tells you there is more than one inode table (one for every formatted partition + virtual file systems)
8. Look at the directories /etc/init.d/ /etc/rc.d/ /etc/rc3.d/ ... do you see the links ?
ls -l /etc/init.d
ls -l /etc/rc2.d
ls -l /etc/rc3.d
9. Look in /lib with ls -l...
ls -l /lib
10. Use find to look in your home directory for regular files that
have more than one hard link (hint: this is identical to all regular
files that do not have exactly one hard link).
find ~ ! -links 1 -type f