Table of Contents
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 inode is.
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 -l 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/
The inode table contains all of the inodes and is created when you create the file system (with mkfs). You can use the df -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.
Each inode has a unique number (the inode number). You can see the inode numbers with the ls -li 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).
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.
A directory is a special kind of file that contains a table which maps filenames to inodes. Listing our current directory with ls -ali 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$
When we create a hard link to a file with ln, 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.
You can use the find 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 inode number is unique to its partition.
paul@RHELv4u4:~/test$ find / -inum 817270 2> /dev/null /data/sites/web/cobbautbe/subsites/test/file2 /data/sites/web/cobbautbe/subsites/test/hardlink_to_file2
Symbolic links (sometimes called soft links) do not link to inodes, but create a name to name mapping. Symbolic links are created with ln -s. As you can see below, the symbolic 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).
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
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 do not(!) have one hard link.
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 do not(!) have one hard link.
find ~ ! -links 1 -type f