What the difference between a symbolic link and a hard link?

Symbolic link creates a new inode and contains a pointer to the original file/directory.

Both are pointers to files


Creating a Symbolic Link

A symbolic link points to another file by name. It has a special mode bit that identifies it as a symbolic link, and its contents are the name of the real file. Because it just contains a name, that name does not actually have to exist, or may exist on a different filesystem. If you replace the named file, then the link still contains the same name, and so now it points to the new file. You can easily identify a symbolic link and see the name of the file it points to.

$ ln -s <source> <linkname>

usernam@lap:~$ mkdir test
usernam@lap:~$ mkdir test2
usernam@lap:~$ pwd
usernam@lap:~$ ln -s /home/local//MAT/usernam/test test2

usernam@lap::~/test2$ ls -l
total 0
lrwxrwxrwx 1 usernam domain^users 29 Feb 14 14:52 test -> /home/local//MAT/usernam/test


The format linkname -> target is how all symlinks show, whether they are linking to a file or a directory. You may also notice that the file type shows as l for symbolic link.

Creating Hard Links

$ ln <source> <linkname>
$ ln file.real file.hard

$ ls -l
total 8
-rw-rw-r-- 2 madflojo madflojo 18 Oct 9 18:49 file.hard
-rw-rw-r-- 2 madflojo madflojo 18 Oct 9 18:49 file.real
lrwxrwxrwx 1 madflojo madflojo 9 Oct 9 18:49 file.sym -> file.real

$ cat file.hard
This is file.real
As far as the file system is concerned there is no difference between file.real and file.hard as they are both references to the same inode (10097087).

The only way to even show that file.hard is a hard link is to look at the links count in the inode. You can do this with the stat command.

$ stat file.hard 
 File: file.hard
 Size: 18 Blocks: 8 IO Block: 4096 regular file
Device: fc00h/64512d Inode: 10097087 Links: 2
Access: (0664/-rw-rw-r--) Uid: ( 1001/madflojo) Gid: ( 1001/madflojo)
Access: 2013-10-09 18:56:36.079158024 -0700
Modify: 2013-10-09 18:49:46.477126917 -0700
Change: 2013-10-09 18:56:29.903127399 -0700
 Birth: -

While this shows that the inode for file.hard has 2 links it does not necessarily show which is the original file and which is the hard link.

A hard link points to the file by inode number. As such, hard links are no different than the first name of a file. There is no “real” name vs. hard link name; all hard links are equally valid names for the file. Because of this, the file you link to must actually exist and be in the same filesystem where you are trying to create the link.

If you delete the original name, then the hard link still points to the same file. Because all hard links are equally valid name(s) for the file, you can not look at one and see the other names for the file; to find this, you have to go looking at every file and compare their inode number to find the other name(s) that have the same inode number.

You can tell how many names a file has from the output of ls -l. The first number after the file mode is the link count. A file with more than 1 link has other name(s) somewhere, and conversely, a file with a link count of only 1 has no (other) hard links.

With hard links you can delete the original file

Since a hard link is simply a reference to an inode, you can actually delete the original file and the data will still be available via the hard link.


The benefits of using hard links in this scenario are:

  • I can have a file in two places without having to duplicate data on disk
  • Each Hard Link does not increase the number of inodes, this will help if this system processes a large amount of files
  • I can use the stat or find commands to identify the current number of hard links to a file to identify which files have finished processing

The symlink is now a “broken” link where as the hard link is now indistinguishable from any other file.