Symbolic Links in Linux: Create, Inspect, and Fix Symlinks
Learn how Linux symbolic links work, how they differ from hard links, and how to create, inspect, replace, delete, and repair symlinks with ln.
A symbolic link, commonly called a symlink or soft link, is a special filesystem entry that stores a pathname to another file or directory. The referenced file or directory is the target.
A symlink is a separate filesystem object. It does not contain a copy of the target's data. When an application accesses the symlink, the operating system reads the stored pathname and resolves it to the target before performing the requested operation.
Symlinks are useful for creating convenient aliases, maintaining stable paths for applications, sharing resources between directory trees, and redirecting an old path to a new location.
How Symbolic Links Differ from Hard Links
An inode is a filesystem metadata structure that identifies a file object and records information such as ownership, permissions, size, and timestamps. A hard link is an additional directory entry for the same inode and underlying file data.
| Characteristic | Symbolic Link | Hard Link |
|---|---|---|
| What it references | A pathname stored inside the symlink | The same inode and file data as the original directory entry |
| Inode relationship | The symlink has its own inode | Both names share one inode |
| Can cross filesystems or partitions | Yes, because it stores a path | No; the inode must be in the same filesystem |
| Can link to directories | Yes | Ordinary users are generally restricted from creating directory hard links |
| If the original pathname is deleted | The symlink becomes dangling or broken | Other hard-link names still access the data |
| Can become broken | Yes, if its stored path no longer resolves | No in the same sense; the data remains while at least one hard link exists |
Typical ls -l appearance | link -> target, with a leading l | Looks like an ordinary file name |
Symlink metadata should not be confused with target metadata. A symlink has its own inode and ownership information, while access permissions normally come from the target and the parent directories encountered when the link is followed. The permission display for a symlink is not a substitute for inspecting the target's permissions.
Creating Symbolic Links with ln
The ln command creates links. Use its -s option to create a symbolic link:
ln -s TARGET LINK_NAME
The order matters: write the existing or intended target first, then the pathname to assign to the symlink. The link pathname can be a full path or a name in the current directory.
Link to a Regular File
mkdir -p ~/symlink-demo
printf 'first version\n' > ~/symlink-demo/report.txt
ln -s ~/symlink-demo/report.txt ~/symlink-demo/report-link.txt
ls -l ~/symlink-demo/report.txt ~/symlink-demo/report-link.txt
cat ~/symlink-demo/report-link.txt
The output for the link includes an arrow similar to report-link.txt -> /home/user/symlink-demo/report.txt. Reading through the link reads the target file.
Link to a Directory
mkdir -p ~/symlink-demo/project/assets
printf 'logo data\n' > ~/symlink-demo/project/assets/logo.txt
ln -s ~/symlink-demo/project/assets ~/symlink-demo/assets-link
ls -l ~/symlink-demo/assets-link
ls ~/symlink-demo/assets-link
cd ~/symlink-demo/assets-link
pwd
Directory navigation through a valid symlink reaches the target directory. Choose a meaningful link name and put it where users or programs expect the convenient path to exist.
Replacing an Existing Symlink
ln normally refuses to create a link when the destination name already exists. For a deliberate update, GNU and many Unix implementations support:
ln -sfn NEW_TARGET LINK_NAME
-f requests removal of an existing destination, and -n prevents a symlink to a directory from being treated as a directory during the update. This command can be destructive or confusing if the destination is a real file or directory. Inspect it first:
ls -ld LINK_NAME
Use the force/update form only after verifying the expected target and confirming that replacing the destination is safe. In scripts, quote paths and validate the destination before replacement.
Absolute and Relative Symlink Targets
An absolute path begins at the filesystem root, such as /home/user/documents/report.txt. A relative path is interpreted from a relevant directory rather than from the root.
| Target Style | Example Form | Strengths | Limitations | Best Use Case |
|---|---|---|---|---|
| Absolute | /home/user/documents/report.txt | Unambiguous regardless of the link's parent directory | May stop working if the target tree is moved or mounted elsewhere | System paths or locations that are intentionally fixed |
| Relative | ../shared/config.ini | Can remain valid when a complete project tree moves together | Depends on the symlink's containing directory and correct layout | Portable project directories and self-contained directory trees |
A relative target is interpreted relative to the directory containing the symlink, not relative to the shell's current working directory when someone later accesses the link.
mkdir -p project/app project/shared
printf 'debug=true\n' > project/shared/config.ini
cd project/app
ln -s ../shared/config.ini app-config.ini
readlink app-config.ini
cat app-config.ini
Here, app-config.ini is inside project/app. Therefore ../shared/config.ini means project/shared/config.ini. If the whole project directory is moved together, the relative relationship remains intact. An absolute link to the old project location may fail after the move.
To create an absolute link, use the full target path:
ln -s /home/user/documents/report.txt ~/report-link.txt
Inspecting Symbolic Links
Use ls -l
In long listing output, a symlink has a leading l file-type character and displays its stored target after an arrow:
ls -l ~/symlink-demo/report-link.txt
The arrow shows the pathname stored in the symlink. It does not guarantee that the target currently exists.
Use readlink and realpath
readlink ~/symlink-demo/report-link.txt
readlink -f ~/symlink-demo/report-link.txt
realpath ~/symlink-demo/report-link.txt
readlink prints the stored target path without necessarily resolving it. readlink -f and realpath attempt to produce a canonical path: a normalized path with symlink components followed where possible. Resolution commands are most useful when the target exists; behavior and output for broken paths can vary by implementation.
Compare Inodes
ls -li ~/symlink-demo/report.txt ~/symlink-demo/report-link.txt
stat ~/symlink-demo/report.txt ~/symlink-demo/report-link.txt
The target and symlink should have different inode numbers. This demonstrates that the symlink is not another name for the same inode; it is a separate object containing a pathname.
Using a Valid Symbolic Link
Normal file operations follow a valid symlink:
printf 'updated version\n' > ~/symlink-demo/report.txt
cat ~/symlink-demo/report-link.txt
echo 'another line' >> ~/symlink-demo/report-link.txt
cat ~/symlink-demo/report.txt
Changing the target through its original pathname is visible through the link, and editing through the link changes the target. This is different from modifying the symlink itself. Operations that inspect or remove the link must be performed with care so they do not unintentionally follow it.
Deleting and Updating Links
Remove a symlink by giving rm the link pathname:
rm ~/symlink-demo/report-link.txt
ls ~/symlink-demo/report.txt
This removes only the symlink. It does not remove the target. Conversely, deleting or moving the target does not delete the symlink; it leaves a dangling link behind.
For a directory symlink, do not add a trailing slash to the link name in a removal command. A trailing slash can cause the command to treat the path as a directory, follow the link, or fail in an unexpected way. Use the symlink pathname itself:
ln -s ~/symlink-demo/project/assets ~/symlink-demo/assets-link
rm ~/symlink-demo/assets-link
ls ~/symlink-demo/project/assets
To recreate or update a link, remove the obsolete symlink and create a new one, or use a carefully verified update command such as ln -sfn.
Broken or Dangling Symlinks
A dangling symlink, also called a broken symlink, is a symlink whose stored target path no longer exists. The target may have been deleted, renamed, moved, or made unreachable because a relative path was calculated incorrectly.
printf 'temporary data\n' > ~/symlink-demo/old.txt
ln -s old.txt ~/symlink-demo/old-link.txt
rm ~/symlink-demo/old.txt
ls -l ~/symlink-demo/old-link.txt
cat ~/symlink-demo/old-link.txt
ls still shows the link and its arrow, often with a visually emphasized or missing target depending on the terminal. An access attempt fails because the stored path cannot be resolved.
Inspect the stored path and find dangling links below a directory:
readlink ~/symlink-demo/old-link.txt
find ~/symlink-demo -xtype l
The -xtype l test identifies symbolic links whose targets cannot be followed. Unlike tests that inspect the target type, this use of find is intended to locate dangling links without following valid link targets as directory trees.
A broken link has three typical resolutions:
- Restore the target at the pathname stored in the link.
- Replace the link so it points to the target's new location.
- Remove the obsolete symlink if it is no longer needed.
Common Commands for Symbolic Links
| Command | Purpose | Key Notes |
|---|---|---|
ln -s TARGET LINK_NAME | Create a symbolic link | Target comes first; link pathname comes second |
ls -l LINK_NAME | Display link type and stored target | Look for a leading l and -> |
ls -li TARGET LINK_NAME | Compare inode numbers | A symlink and target have different inodes |
readlink LINK_NAME | Print the stored target path | Does not necessarily produce a canonical path |
readlink -f LINK_NAME | Resolve to a canonical path | Most useful when the target exists |
realpath LINK_NAME | Resolve a path canonically | Resolution requires a usable path |
rm LINK_NAME | Remove the symlink | Do not append a trailing slash to a directory link |
find DIRECTORY -xtype l | Find dangling symlinks | Searches below the specified directory |
Troubleshooting Symlinks
The Link Says “No Such File or Directory”
First inspect the recorded target:
ls -l LINK_NAME
readlink LINK_NAME
For an absolute target, check that exact path. For a relative target, start from the directory containing the symlink and evaluate the relative pathname from there. Restore, rename, or move the target back into place; replace the link with the correct target; or remove the obsolete link.
A Relative Link Breaks After Moving Files
The link and target may not have been moved together, or the relative pathname may have been written relative to the wrong directory. Identify the link's parent directory, resolve the stored path from that directory, and compare it with the actual target location. Correct the relative path or use an absolute path when the location is intentionally fixed.
ln Reports That the Destination Exists
The requested link name may already be a file, directory, or symlink:
ls -ld LINK_NAME
Choose another name, remove an obsolete symlink, or use a deliberate force/update option after confirming that the destination is safe to replace. Never assume an existing destination is disposable.
Access Is Denied
A symlink does not bypass permissions. When it is followed, permissions on the target and on each parent directory in the path still control access. Inspect the target and its parent directories, along with ownership and applicable access controls. See Manage File Ownership for related ownership concepts.
Practical Safety Rules
- Quote paths containing spaces or shell metacharacters:
ln -s "/path/with spaces/file" "/path/with spaces/link". - Remember that a link can be created before its target exists. This can be intentional, but validate the target before relying on the link.
- Be explicit about the link pathname. When the destination is a directory,
ln -s TARGET DIRECTORYcreates a link inside that directory, which may not be the name you expected. - Before replacing a link, inspect it with
ls -ldand verify the intended target. A force option can remove an existing path. - Use
ls -liorstatwhen you need to distinguish a symlink object from the target inode. - Remember that symlinks can cross filesystem and partition boundaries, but the target must still be reachable and accessible.
Exam-Relevant Summary
- A symlink is a special filesystem entry containing a pathname, not a copy of target data.
- The operating system resolves the stored path when the link is accessed.
- Create one with
ln -s TARGET LINK_NAME; the target is written before the link pathname. - A symlink has its own inode. A hard link shares the target's inode.
- Symlinks can point to directories and cross filesystem or partition boundaries.
- Deleting a target leaves a dangling symlink; deleting the symlink normally leaves the target untouched.
ls -lshows a leadinglandlink -> target;readlinkprints the stored path.- Relative targets are resolved from the symlink's containing directory, not from the current directory used later to access the link.
- Target permissions control access after a symlink is followed.