Hard Links vs Symbolic Links in Linux: Inodes, Paths, and the ln Command

Glass file directory illustrating hard links vs symbolic links in Linux Linux & Administration
Learn the difference between hard links and symbolic links in Linux. Understand how inodes and paths work, use the ln command, and explore practical examples.
Linux & Administration · Filesystem Fundamentals

Two Linux filenames can open exactly the same data without being copies of each other. But rename one of those files, and you may discover that one link continues to work while another becomes broken.

The difference becomes clear once you understand three things: directory entries, inodes, and path resolution. This guide explains hard links vs symbolic links, how the ln command creates them, and how to inspect their behavior safely on a Linux server.

⚡ Quick Answer

A hard link is another directory entry that refers to the same inode as an existing file. Both names provide access to the same underlying file. Renaming or removing one name does not invalidate the other.

A symbolic link, also called a symlink or soft link, is a separate filesystem object that stores a pathname. When a program follows that link, Linux resolves the stored path to find the target.

The practical difference is simple: a hard link refers to the file object, while a symbolic link refers to a path. That distinction explains most of their behavior.

🎯 What You’ll Learn
  • Why Linux separates filenames from the underlying file objects.
  • How directory entries and inodes fit together.
  • What hard links and symbolic links actually reference.
  • How to create and inspect links with ln, ls, stat, and readlink.
  • Why some links survive renames while others break.
  • How to choose the appropriate link type on a Linux server.

🧠 The Mental Model: A Filename Is Not the File

Start with a common assumption: a filename is the file itself.

Linux filesystems work differently. In a typical Unix-style filesystem, a directory contains entries that associate names with inode numbers. An inode represents a filesystem object and records information such as its type, permissions, ownership, timestamps, and references to its data.

The name is part of a directory entry. It is not normally stored as the filename inside the inode.

For example, when you open /home/alex/report.txt, Linux resolves the components of that pathname through the filesystem until it reaches the object associated with the final name.

Understanding this distinction is an important next step after learning the Linux filesystem directory structure.

One file object. Different ways to reach it.
🔗 Hard Links
report.txt + alias.txt
SAME INODE File contents

Two directory entries refer directly to the same inode. Neither filename is inherently more original than the other.

🧭 Symbolic Link
shortcut.txt Stored path: report.txt Path lookup Target inode

The symlink has its own filesystem identity and stores a path that must resolve successfully to reach the target.

Conceptual illustration. Inode numbers identify objects within a filesystem; the diagram simplifies Linux pathname resolution for learning purposes.

Both link types help users reach files through different names. However, their relationships to the underlying objects are fundamentally different.

💎 What Is an Inode in Linux?

An inode is a filesystem data structure used to represent a file or another filesystem object.

On common Linux filesystems, inode metadata includes information such as:

  • file type;
  • owner and group identifiers;
  • permission bits;
  • file size;
  • timestamps;
  • hard-link count;
  • information needed to locate the file’s data.

Inode numbers are meaningful within a filesystem. Two different filesystems can use the same inode number for unrelated objects.

This is one reason inode numbers should not be interpreted without their filesystem or device context.

How to See an Inode Number

The ls -i command displays inode numbers alongside filenames.

Terminal Read-only
ls -i

The numbers depend on your filesystem and will differ between systems.

You can also inspect a specific object’s inode and hard-link count with GNU stat:

Terminal Read-only
stat -c 'Inode: %i | Links: %h | Name: %n' /etc/hosts

The %i field displays the inode number. The %h field shows how many hard links refer to that object.

Inodes are part of the broader storage model. To understand how filesystems relate to partitions and mount points, see Linux Storage Explained.

A hard link creates another name for an existing filesystem object.

When you create a hard link to a regular file, Linux adds another directory entry referring to the same inode.

It does not create a separate copy of the file’s contents.

Suppose a file named report.txt already exists. You can create another name for it with:

Terminal Create a hard link
ln report.txt alias.txt

Both names now identify the same underlying file. Reading either name accesses the same contents, and modifications made through either name affect that shared object.

Imagine that both filenames contain the text Production settings.

If a program overwrites the file through alias.txt, opening report.txt shows the changed data too.

Both names refer to the same file object, so there are not two independent copies to recover from.

⚠️ Important

A hard link does not protect against accidental modification, corruption, or deletion of a file’s contents. Use an actual backup when you need an independently recoverable copy.

Removing one hard-linked filename removes that directory entry and decreases the inode’s link count.

If another hard link still exists, the file remains accessible through that other name.

When the final hard link is removed, the filesystem can reclaim the object once no remaining references, such as open file descriptors, require it.

This behavior explains why removing a filename does not always immediately release all storage used by the underlying file.

A symbolic link works through a pathname rather than a direct shared-inode relationship.

Unlike a hard link, a symlink is a separate filesystem object. It stores a string representing a path to another object.

For example:

Terminal Create a symbolic link
ln -s report.txt shortcut.txt

Here, shortcut.txt is a symbolic link containing the relative pathname report.txt.

When a program opens shortcut.txt, Linux normally follows that pathname and attempts to open the target.

If report.txt no longer exists at the expected location, the symlink may become broken.

Suppose you rename report.txt to report-old.txt.

The symbolic link still contains the original pathname. Linux does not automatically rewrite that stored string.

Consequently, opening the link may fail because the pathname no longer resolves.

The symbolic link itself still exists. Its target simply cannot be found through the stored path.

Symbolic links can store either relative or absolute paths.

📍

Relative Path

A relative symlink stores a path such as ../config/app.conf. Linux interprets it relative to the directory containing the symlink.

🌐

Absolute Path

An absolute symlink stores a path beginning with /, such as /etc/app/config.conf. Resolution begins from the process’s root directory.

Relative links can remain valid when a complete directory tree is moved without changing the internal relationship between its files.

Absolute links can be useful when the target has a stable system-wide location, but they may break if that location changes.

Neither approach is universally better. The correct choice depends on where the symlink will be stored and how the target path is expected to change.

The following comparison summarizes the practical differences between the two link types on typical Linux filesystems.

Property Hard Link Symbolic Link
References The same inode A stored pathname
Own inode Shares the target file’s inode Has its own inode
Copies file data No No
Survives removal of another filename Yes, while another hard link remains Only if its stored path still resolves
Crosses filesystem boundaries No Can reference paths on other filesystems
Links to directories Normally prohibited Supported
Can point to a missing target No, when creating an ordinary hard link Yes
Command ln ln -s

When comparing hard links vs symbolic links, remember that neither creates an independent backup. Their purpose is to provide different ways of referring to filesystem objects.

A hard link must refer to an inode within the same filesystem.

Inode numbers are not globally unique across Linux. They are interpreted together with the filesystem or device containing them.

A directory entry on one filesystem cannot simply establish an ordinary hard-link relationship with an inode belonging to another filesystem.

A symbolic link is different. Because it stores a pathname, that path can resolve to an object located on another mounted filesystem.

For example, a symlink in your home directory might refer to a file stored on a separate mounted data volume.

Whether opening it succeeds depends on the target path being reachable and the necessary permissions being available.

💡 Remember

A hard link is constrained by filesystem identity. A symbolic link is constrained by pathname resolution.

Hard links share the same inode, so they share the file’s ownership, permission bits, and other inode-level metadata.

Changing the permissions through one hard-linked filename changes the permissions observed through the other.

Symbolic links have their own metadata, but on Linux the symlink’s permission bits are generally not used to authorize ordinary access to the target.

When a program follows a symbolic link, access checks apply to the target and the directories involved in resolving its path.

Creating a symbolic link therefore does not bypass the permissions of the target file.

For a fuller explanation of ownership and access checks, read Linux File Permissions Explained.

Linux provides several commands for examining file links without modifying them.

📂

ls -li

Displays filenames, inode numbers, link counts, and file metadata. Helpful for noticing hard-linked names that share an inode.

🧬

stat

Displays detailed metadata for a filesystem object, including its inode number, type, ownership, and link count.

🧭

Displays the pathname stored inside a symbolic link. Useful when investigating unexpected link destinations.

🔍

find

Can locate filesystem objects and, with suitable predicates, identify names that refer to the same underlying file.

For more on file discovery and search conditions, see Linux find Command Explained.

This experiment demonstrates the difference between hard links and symbolic links without changing system configuration.

It uses a temporary directory and ordinary files. No administrator privileges are required.

🧪 Lab Objective

Create two names for one inode and one symbolic link to a pathname. Then rename the original filename and observe which references continue to work.

Step 1: Create a Temporary Workspace

Terminal Temporary workspace
lab_dir="$(mktemp -d)"

printf 'Linux link experiment\n' > "$lab_dir/original.txt"

printf 'Workspace: %s\n' "$lab_dir"

The mktemp -d command creates a new temporary directory. Save the reported path if you want to inspect the files manually afterward.

Terminal Hard link
ln "$lab_dir/original.txt" "$lab_dir/alias.txt"

The new filename alias.txt refers to the same inode as original.txt.

Terminal Symbolic link
ln -s original.txt "$lab_dir/shortcut.txt"

Here the symbolic link stores the relative path original.txt. That path is interpreted relative to the directory containing shortcut.txt.

Step 4: Inspect the Inodes

Terminal Read-only inspection
ls -li "$lab_dir"

stat -c '%n | inode=%i | links=%h' \
  "$lab_dir/original.txt" \
  "$lab_dir/alias.txt" \
  "$lab_dir/shortcut.txt"

Look for three observations:

  • original.txt and alias.txt have the same inode number.
  • The shared regular file normally has a hard-link count of 2.
  • shortcut.txt has its own inode because it is a separate symbolic-link object.

GNU stat normally inspects the symbolic link itself unless you request target dereferencing with -L.

Terminal Read-only inspection
readlink "$lab_dir/shortcut.txt"

The expected output is:

Expected output Example
original.txt

This is the pathname stored in the symlink, not the inode number of the target.

Step 6: Rename the Original Filename

Terminal Controlled rename
mv "$lab_dir/original.txt" "$lab_dir/renamed.txt"

The file object has not been replaced. Only one directory entry’s name has changed.

Now read the contents through the hard link:

Terminal Read-only verification
cat "$lab_dir/alias.txt"

You should still see:

Expected output
Linux link experiment

The hard link remains valid because it still refers to the same inode.

Terminal Read-only verification
if [ -L "$lab_dir/shortcut.txt" ]; then
  printf 'The symbolic link still exists.\n'
fi

if [ -e "$lab_dir/shortcut.txt" ]; then
  printf 'Its target resolves.\n'
else
  printf 'Its target no longer resolves.\n'
fi

The symbolic link still exists, but its stored pathname still says original.txt.

Since that pathname no longer identifies the renamed file, the link is dangling.

Notice the distinction: test -L checks whether the object is a symbolic link, while test -e follows the link when checking whether its target exists.

Step 8: Find Names That Share the Same File

Terminal GNU find
find "$lab_dir" -maxdepth 1 -type f \
  -samefile "$lab_dir/alias.txt"

The expected matches are alias.txt and renamed.txt.

The -samefile predicate checks filesystem identity rather than merely comparing filenames or file contents.

Step 9: Clean Up the Lab

Before deleting anything, display the temporary workspace path and verify that it is the directory created for this experiment.

Terminal Verify workspace
printf 'Lab directory: %s\n' "$lab_dir"

ls -la "$lab_dir"

Once you have confirmed the path, remove only the three files created in the lab and then the now-empty directory:

Terminal Cleanup after verification
if [ -n "$lab_dir" ] && [ -d "$lab_dir" ]; then
  rm -- "$lab_dir/shortcut.txt" \
        "$lab_dir/alias.txt" \
        "$lab_dir/renamed.txt"

  rmdir -- "$lab_dir"
fi

These commands assume the earlier steps completed successfully. Run them only after checking the temporary path. No recursive deletion is required.

Thinking a hard link is a separate copy

Hard-linked names share the same file object. Changes to its data are visible through all hard links.

Assuming one hard-linked filename is the original

After the second directory entry has been created, both names are peers. The filesystem does not assign one a special original-file status.

Expecting a symlink to follow a renamed file

Symlinks store path strings. Renaming the target may leave the stored pathname pointing somewhere that no longer exists.

Using a hard link across filesystems

Hard links cannot cross filesystem boundaries. Use a symbolic link when pathname-based access to another mounted filesystem is appropriate.

Confusing symlink permissions with target permissions

A symbolic link does not automatically grant access to its target. Normal filesystem permission checks still apply.

Using forced replacement without checking the destination

Avoid running ln -f or replacing an existing link on a production server until you understand what currently exists at that path.

The better choice depends on what relationship you want to preserve.

  • You need another filename for the same regular file.
  • Both names are located on the same filesystem.
  • You want access through one name to remain valid if another name is removed.
  • You understand that both names share the same data and metadata.
  • You want a convenient alias for a file or directory.
  • The target may be located on another filesystem.
  • You intentionally want the link to represent a particular pathname.
  • You need a stable public path that can be redirected to a different versioned directory or file.

A common server example is a deployment directory:

Conceptual example Directory layout
/srv/application/
├── releases/
│   ├── release-a/
│   └── release-b/
└── current -> releases/release-b/

Here, current is a symbolic link to a release directory. Applications can refer to one stable pathname while administrators manage versioned directories behind it.

This is an example of deliberate pathname indirection. It would not normally be implemented with a hard link because ordinary hard links to directories are prohibited.

✅ Practical Rule

Choose a hard link when you need another name for the same file object on the same filesystem.

Choose a symbolic link when you need a pathname-based reference that may point to a file, directory, or object on another filesystem.

🧠 Knowledge Check

Test your understanding of the relationship between names, inodes, and filesystem objects.

1. Do two hard links contain two independent copies of a file?

No. The two directory entries reference the same inode and the same underlying file contents. Modifying data through either name affects the shared object.

2. Why can a symbolic link break after its target is renamed?

Because the symlink stores a pathname. Renaming the target does not automatically change that stored pathname, so it may no longer resolve.

3. What happens when one of two hard-linked filenames is removed?

The removed directory entry disappears and the link count decreases. The file remains accessible through the other hard link.

4. Why can’t an ordinary hard link cross filesystem boundaries?

A hard link is a directory entry referring to an inode within the same filesystem. Inode numbers and their identities are filesystem-specific, so a cross-filesystem hard link is not supported.

5. Does deleting a symbolic link normally delete its target?

No. Removing a symlink normally removes the link object itself, not the file or directory identified by its stored target pathname.

6. Which command helps inspect the pathname stored in a symlink?

readlink displays the stored pathname. For example, readlink shortcut.txt can show the path recorded by that symbolic link.

🎓 Servers Academy — Key Takeaway

The difference between hard links vs symbolic links comes down to what each link references.

A hard link is another directory entry for the same inode. A symbolic link is a separate filesystem object containing a pathname that must be resolved.

Once you understand that distinction, link counts, broken symlinks, file renames, and many common filesystem behaviors become much easier to reason about.

The most important lesson is broader than the ln command: on Linux, a filename is a way to reach a filesystem object, not necessarily the object’s identity.

📚 Official References

The following primary technical sources explain Linux inode metadata, symbolic-link behavior, and the GNU tools used in this lesson.

Rate article
Servers Academy
Add a comment