Linux Tutorial / Hard Links vs. Symbolic Links in Linux: Differences and Examples

A hard link is another name for the same file inode, whereas a symbolic link is a separate entry that stores a path to another location. Both offer another way to reach a file, but they behave differently when the original name changes or a file-system boundary is involved. In this lesson, you will create both links and observe the difference.

Two ideas behind file links

A directory entry such as report.txt supplies a name used in a path. The file system manages the file's metadata using an inode. Adding a hard link creates another name for the same inode. If one of those names is removed, the other still gives access to the file as long as it remains.

A symbolic link is its own entry containing the path string of its target. The system follows that path when you open the link. If the named target disappears or moves, the link can remain while access through it fails. This is called a broken link.

Comparison Hard link Symbolic link
What it refers to The same file inode A target path string
Inode Same as the original name Has its own inode
Original name removed or changed The other name still works Can break if the stored path no longer resolves
Another file system Cannot cross the boundary Can point to a path on another file system
Directory target Generally cannot be created Can be created

Create a practice file and both links

Work inside a new directory in your home folder. If ~/linux-course-09-practice already exists, choose a different name. The mkdir command below fails when the directory already exists. Stop if that happens: continuing might overwrite an existing file.

mkdir ~/linux-course-09-practice
cd ~/linux-course-09-practice
pwd

Check that pwd names the directory you just created before making a file. The following printf writes one line into original.txt.

printf 'version 1\n' > original.txt
ln original.txt hard.txt
ln -s original.txt shortcut.txt

The first ln uses its default behavior to create a hard link. The second creates a symbolic link with -s. shortcut.txt stores the relative path original.txt. Interpret that path relative to the directory containing the link, not the shell's current working directory.

Inspect inodes and the link target

Use GNU stat to display inode number (%i) and hard-link count (%h). readlink prints the path stored in a symbolic link.

stat -c '%i %h %n' original.txt hard.txt shortcut.txt
readlink shortcut.txt

Actual inode numbers differ by system, but original.txt and hard.txt should share a number and show a link count of two, as in this illustration. shortcut.txt has a different inode.

123456 2 original.txt
123456 2 hard.txt
789012 1 shortcut.txt
original.txt

These numbers are examples, not measured results. The relative path original.txt printed by readlink resolves within the directory holding the link, so all three names currently give access to the same content.

cat original.txt
cat hard.txt
cat shortcut.txt

Each command prints version 1. Identical content, however, does not mean the three names have the same underlying structure.

What if the original name changes?

Rename original.txt inside the practice directory. hard.txt remains readable because it names the same inode. shortcut.txt still points to the old path original.txt, so it becomes broken.

mv original.txt renamed.txt
cat hard.txt
readlink shortcut.txt

cat hard.txt prints version 1, while readlink shortcut.txt still prints original.txt. At this point, cat shortcut.txt should report that the target cannot be found. To make a link to the new name in the same directory, you could run ln -s renamed.txt new-shortcut.txt.

Removing a symbolic link with rm shortcut.txt normally removes the link itself, not the target. A trailing slash or a command aimed at a file inside a linked directory can change what a path means, however. Check the exact target before deleting anything.

Which link should you use?

Use a hard link when you want another name for a file on the same file system and want the file to remain accessible if one name disappears. A symbolic link is more flexible when you need to refer to a directory or a path on another file system, or want the destination to be visible as a path. If you plan to move the symbolic link or rename its target, remember that a relative target is interpreted from the link's own directory.

For more on destination handling and options, see the ln command guide. The readlink guide explains the stored target path and its resolution in more detail.

Official documentation

The GNU Coreutils ln documentation covers hard and symbolic links, and the GNU readlink documentation covers target-path output.

More in This Category
Linux sftp Command: Transfer Files Securely over SSH

Linux sftp Command: Transfer Files Securely over SSH

Learn how to use the Linux sftp command to transfer and manage files securely through an SSH connection, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux xz Command: Compress a File in xz Format

Linux xz Command: Compress a File in xz Format

Learn how to compress a File in xz Format with the Linux xz command, including practical examples, key options, and important precautions.

Linux zypper Command: Manage Packages on openSUSE and SUSE

Linux zypper Command: Manage Packages on openSUSE and SUSE

Learn how to manage Packages on openSUSE and SUSE with the Linux zypper command, including practical examples, key options, and important precautions.

Linux fold Command: Wrap Long Lines at a Fixed Width

Linux fold Command: Wrap Long Lines at a Fixed Width

Learn how to wrap Long Lines at a Fixed Width with the Linux fold command, including practical examples, key options, and important precautions.

Linux uptime Command: Check Uptime and Load Averages

Linux uptime Command: Check Uptime and Load Averages

Learn how to use the Linux uptime command to check how long the system has been running and interpret load averages, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux timedatectl Command: Check Time Zone and Time Synchronization

Linux timedatectl Command: Check Time Zone and Time Synchronization

Learn how to check Time Zone and Time Synchronization with the Linux timedatectl command, including practical examples, key options, and important precautions.

Linux sync Command: Flush Buffered Writes to Storage

Linux sync Command: Flush Buffered Writes to Storage

Learn how to flush Buffered Writes to Storage with the Linux sync command, including practical examples, key options, and important precautions.

Linux dnf Command: Manage RPM Distribution Packages

Linux dnf Command: Manage RPM Distribution Packages

Learn how to manage RPM Distribution Packages with the Linux dnf command, including practical examples, key options, and important precautions.

Linux tracepath Command: Trace a Network Path and Path MTU

Linux tracepath Command: Trace a Network Path and Path MTU

Learn how to trace a Network Path and Path MTU with the Linux tracepath command, including practical examples, key options, and important precautions.

Linux alias Command: Create Command Shortcuts

Linux alias Command: Create Command Shortcuts

Learn how to use the Linux alias command to create, inspect, and make shell command aliases persistent, with essential options, practical examples, output interpretation, and common troubleshooting tips.