Linux Links: Hard Links, Symbolic Links, and the ln Command
Learn how Linux hard links and symbolic links work, how inodes and directory entries relate, and how to create, inspect, replace, and remove links with ln.
Linux links let more than one pathname reach the same file or another path-based resource. Links are useful for convenient alternate locations, compatibility with programs that expect a particular pathname, alternate command names, and avoiding unnecessary duplicate file content.
Linux links resemble shortcuts, but there are two different mechanisms. A hard link is another directory entry for the same inode and data. A symbolic link, also called a symlink or soft link, is a special file that stores a path to another file or directory.
Filesystem Concepts Behind Links
A filename is not the file's contents by itself. A directory contains directory entries: mappings from names to filesystem metadata records. On common Linux filesystems, that metadata record is an inode.
An inode identifies an object and stores information such as ownership, permissions, timestamps, size, file type, and pointers or other information used to locate the file's data. An inode number identifies the inode within a filesystem.
ls -i file.txt
stat file.txt
A directory entry maps a name to an inode. This distinction explains hard links: multiple names can map to one inode. It also explains why deleting a filename does not necessarily delete the underlying data.
The filesystem releases file contents only when all hard-link directory entries for the inode have been removed and no process still has the file open. A process with an open file descriptor can continue using the data even after every visible pathname has been removed.
Hard Links
A hard link is an additional directory entry referring directly to an existing inode. After creation, the original name and the new name are equivalent names. Neither is inherently the primary copy.
Hard-linked names share the same inode number, ownership, permissions, timestamps, size, and file contents. Editing through either pathname changes the data visible through both names.
printf 'project notes\n' > notes.txt
ln notes.txt notes-copy.txt
ls -li notes.txt notes-copy.txt
The two lines from ls -li have the same inode number. The link count also increases. In long listing output, ls -l displays the number of hard-link directory entries after the file type and permissions.
rm notes.txt
cat notes-copy.txt
ls -li notes-copy.txt
Removing notes.txt removes one directory entry. The data remains accessible through notes-copy.txt, whose link count is now lower.
Hard-Link Restrictions
- Ordinary hard links cannot cross a filesystem boundary, such as between two separately mounted filesystems.
- Linux generally does not permit users to create hard links to directories. This helps protect directory structure and prevent directory cycles.
- Hard links are normally used with regular files on the same filesystem.
ln /home/user/example.txt /mnt/other-filesystem/example.txt
If the two locations are different filesystems, this commonly fails with an “Invalid cross-device link” error. Use a symbolic link or copy the file instead.
Symbolic Links
A symbolic link is a special file whose stored content is a reference path called its target. A symlink has its own inode and metadata, separate from the inode and metadata of its target.
Unlike hard links, symbolic links can point to regular files or directories and can cross filesystem boundaries.
printf 'release data\n' > /tmp/release.txt
ln -s /tmp/release.txt release-current
ls -l release-current
cat release-current
readlink release-current
ls -l normally shows a symbolic link with an arrow pointing to the stored target path. Opening release-current follows the link and reads /tmp/release.txt.
Absolute and Relative Symlink Targets
An absolute path begins at the filesystem root, usually with /. An absolute symlink target refers to that exact location.
ln -s /tmp/release.txt release-current
A relative path is interpreted from a directory. For a symbolic link, the target is interpreted relative to the directory containing the symlink, not relative to the shell's current directory when the link was created.
mkdir -p app/config
printf 'mode=production\n' > app/config/settings.conf
ln -s config/settings.conf app/settings.conf
cat app/settings.conf
Here, config/settings.conf is resolved from app/, the directory containing app/settings.conf. Relative links are useful when a complete directory tree may be moved together. The relationship within that tree can remain valid after relocation.
Dangling Symbolic Links
A dangling symlink, or broken symlink, still exists as a link object, but its stored target path no longer resolves. The target may have been deleted, renamed, moved, or referenced incorrectly.
ln -s /tmp/old-location.txt current-file
rm -f /tmp/old-location.txt
ls -l current-file
readlink current-file
Removing a symlink removes only the symlink object. It does not remove the target. Conversely, removing or moving the target does not automatically remove the symlink.
Symlink Permissions
Linux usually does not use the permission bits displayed for a symlink to decide whether its target can be opened. Access is primarily controlled by the target's permissions and ownership, plus permissions on every directory that must be traversed.
ls -ld linkname target-file
stat linkname target-file
Creating Links with ln
The basic syntax is:
ln TARGET LINK_NAME
Without options, ln creates a hard link. Use -s to create a symbolic link:
ln -s TARGET LINK_NAME
Quote paths containing spaces, wildcard characters, command substitutions, or other shell-special characters.
ln -s 'Project Files/current report.txt' 'current report.txt'
When the Destination Is a Directory
If the final operand already exists as a directory, ln normally creates the link inside that directory. For example, a destination of links/ can result in a new entry named after the target's basename inside links/.
Specify the complete destination path when you want a particular name. On implementations supporting it, -T tells ln to treat the destination as a normal filename rather than as a directory destination.
ln -s /tmp/release.txt links/release-current
ln -sT /tmp/release.txt links
The second command is useful only when links is intended to be treated as the destination name itself. Check your system's ln manual for option support and exact behavior.
Useful ln Options
| Option | Meaning | When to use it |
|---|---|---|
-s | Create a symbolic link. | For directory aliases, cross-filesystem references, and flexible path aliases. |
-f | Force removal of an existing destination before creating the link. | For deliberate noninteractive replacement; use carefully. |
-i | Ask before replacing an existing destination. | For safer interactive operations. |
-n | With supported implementations, treat an existing symlink to a directory as a link rather than following it. | Useful when replacing symlinks that point to directories. |
-T | Treat the destination as a normal filename instead of a directory. | When the destination must not cause creation inside a directory. |
-v | Print what the command is doing. | For confirmation and troubleshooting. |
A common replacement command for an existing symbolic-link name is:
ln -sfn /tmp/new-location.txt current-file
-f allows replacement, -n helps prevent following an existing symlink to a directory, and -s creates a symlink. Use -i instead of a forceful workflow when confirmation is preferred.
Inspecting and Identifying Links
| Command | Purpose | Key observation |
|---|---|---|
ln | Create a hard link by default. | The new name refers to the existing inode. |
ln -s | Create a symbolic link. | The new object stores a target path and has its own inode. |
ls -l | List details. | A symlink normally appears with -> and its target. |
ls -i or ls -li | Show inode numbers and, with long format, link counts. | Matching inode numbers indicate hard links to the same inode. |
stat | Inspect type, inode, link count, and metadata. | Useful for precise comparisons. |
readlink | Print a symlink's stored target. | It does not need to open the target. |
readlink -f | Resolve a path through symlinks. | Typically requires all needed path components to resolve. |
realpath | Print a resolved path. | Behavior for missing components depends on options and implementation. |
find DIRECTORY -type l | Find symbolic links. | Useful for auditing a directory tree. |
rm | Remove a named link. | Removes the hard-link directory entry or symlink object. |
ls -li notes.txt notes-copy.txt
stat notes.txt notes-copy.txt
ls -l release-current
readlink release-current
readlink -f release-current
realpath release-current
find . -type l
find . -xtype l
find -xtype l is available on common GNU find implementations and commonly locates broken symbolic links. Resolution commands can fail or produce different results when a target is missing, so use readlink when you need the stored path even for a broken link.
Deleting, Renaming, and Updating Links
rm LINK_NAME removes the named hard-link entry or symbolic-link object.
rm notes-copy.txt
rm release-current
When removing a symlink to a directory, do not add a trailing slash. A trailing slash can cause a tool to follow the symlink and operate on the target directory instead of removing the link itself.
rm docs
Renaming or deleting a target has different effects:
- A hard link continues to access the same inode even if another hard-link name is renamed or deleted.
- A symbolic link stores a pathname. If that pathname no longer names the target, the symlink becomes dangling.
- After a target relocation, recreate or replace the symlink with its new target path.
ln -sfn /tmp/new-location.txt current-file
Hard Links and Symbolic Links Compared
| Property | Hard link | Symbolic link |
|---|---|---|
| What it references | The same inode and file data. | A stored reference path. |
| Inode relationship | All names share one inode. | The symlink has its own inode; the target has another. |
| Can cross filesystems | No. | Yes. |
| Can link to directories | Generally no for ordinary user-created links. | Yes. |
| If the target pathname is deleted or renamed | The data remains reachable through other hard links. | The symlink can become broken because its stored path no longer resolves. |
| Effect of deleting the link | Removes one directory entry; data remains while another hard link or open file exists. | Removes only the symlink, not its target. |
How it appears in ls -l | Like an ordinary file; compare inode numbers and link counts. | Usually shows an arrow to the target path. |
| Typical use cases | Multiple names for exactly the same regular file within one filesystem. | Aliases, directory references, compatibility paths, and cross-filesystem references. |
Choosing Between the Two
Choose a hard link when all of these requirements fit:
- The names must refer to exactly the same inode and contents.
- The objects are regular files on the same filesystem.
- The link should remain valid when another pathname for the file is renamed or deleted.
Choose a symbolic link when you need flexibility:
- The reference must cross a filesystem boundary.
- The target is a directory.
- You want an explicit alias that can point to a different pathname later.
- An application expects a particular path.
- You are managing a user-facing alternate location or command name.
Symbolic links are normally the flexible default for user-managed aliases and directory references. Hard links are appropriate when multiple names for one regular file are intentional and the same-inode behavior is desired.
Troubleshooting Link Problems
Invalid Cross-Device Link
This error usually means a hard link was requested between different mounted filesystems. Use ln -s, copy the file, or create both hard-link names on one filesystem.
A Symlink Is Visible but Cannot Be Opened
Inspect the stored target with readlink, then check whether it exists. The target may have moved, been renamed, been deleted, or been described with an incorrect relative path.
readlink current-file
ls -l current-file
ln -sfn /correct/path/current-file current-file
The Link Was Created Inside a Directory
If the destination already exists as a directory, ln normally creates an entry inside it. Give the complete intended link path, or use -T where supported when the destination must be treated as a filename.
A Hard Link to a Directory Is Denied
This is normal on Linux. Use a symbolic link for a directory alias.
Relative Link Works in the Wrong Place
Calculate the target relative to the symlink's parent directory. The shell directory used while running ln does not determine how a relative target is later resolved.
Changes Appear Through Both Hard-Link Names
This is expected: both names reach the same inode and data. Use cp when you need an independent copy with separate contents.
Practical Link Checklist
- Decide whether you need the same inode or a reference to a pathname.
- Use
ln TARGET LINK_NAMEfor a hard link andln -s TARGET LINK_NAMEfor a symlink. - Quote paths containing spaces or shell-special characters.
- Check the result with
ls -li,stat, andreadlink. - Use a relative target only when its relationship to the symlink's parent directory is intentional.
- Remove symlinks with
rm LINK_NAME, without a trailing slash.
For related background, review Linux file structure, determining file type, and showing the full path of shell commands.