A symbolic link, also called a symlink or soft link, is a special filesystem entry that contains the path to another file or directory instead of data of its own. In a Linux filesystem, the kernel follows that stored path transparently when a program opens the link, so the program works with the target as if it had opened it directly.
Symbolic links let one object appear under several names and locations, across directories and even across filesystems. They are used everywhere in Linux, from selecting the active version of a library or Java runtime to arranging configuration files, and they differ fundamentally from hard links, which share an inode rather than a path.
How a symbolic link is stored and resolved
A symbolic link is a file of its own with a separate inode and the file type l. Its content is simply a text string with the target path. Many filesystems, including ext4, store short targets directly inside the inode as a fast symlink, which on ext4 applies to targets under 60 bytes; longer targets occupy a data block.
During path resolution, when the kernel meets a symlink in any component of a path, it substitutes the stored path and continues resolving. A relative target is interpreted relative to the directory that contains the link, not to the current working directory of the process. To prevent endless loops, Linux limits the number of links followed in one lookup to 40, after which the call fails with ELOOP.
The target does not need to exist. A link whose target is missing is a dangling or broken symlink: listing it works, but opening it fails with “No such file or directory”. This independence from the target is both the strength and the main risk of symbolic links.
Creating and inspecting symbolic links
Symbolic links are created with ln -s TARGET LINKNAME, a frequent source of confusion because the target comes first, in the same order as cp and mv. The table lists the essential commands.
| Command | Purpose | Note |
|---|---|---|
ln -s target link | Create a symbolic link | Target path is stored exactly as typed |
ln -sfn target link | Replace an existing link | -n avoids descending into a linked directory |
ls -l | Show the link and its target | Displayed as link -> target |
readlink link | Print the stored target | Does not resolve further links |
readlink -f or realpath | Print the fully resolved path | Follows every link in the chain |
find -type l | Find symbolic links | find -xtype l finds broken links |
At the system-call level, stat follows the link and reports the target, while lstat reports the link itself. Tools offer the same distinction through options: cp -P copies links as links, cp -L copies the target data, and tar and rsync preserve links by default or on request.
Symbolic links compared with hard links
The closest neighbor of a symbolic link is the hard link, a second directory entry pointing to the same inode. The two behave very differently, as the comparison shows.
| Property | Symbolic link | Hard link |
|---|---|---|
| What it references | A path string | An inode directly |
| Own inode | Yes | No, shares the target inode |
| Across filesystems | Allowed | Not allowed |
| Link to a directory | Allowed | Not allowed for users |
| Target deleted or moved | Link breaks | Data remains reachable |
| Effect on link count | None | Increases the inode link count |
| Visible in ls -l | Shown with an arrow | Looks like an ordinary file |
Because a symlink stores only a path, renaming the target breaks it, while a hard link survives any rename. Conversely, hard links cannot cross mount points, so a link from /home to a file on another partition must be symbolic.
Typical uses in Linux systems
Symbolic links provide a stable name in front of a changeable target, which is why package managers and administrators rely on them.
| Use case | Example | Benefit |
|---|---|---|
| Shared library versions | libssl.so.3 pointing to a versioned file | Programs find the current compatible version |
| Alternatives systems | /usr/bin/java pointing to a selected runtime | Switch defaults without changing programs |
| Merged directory layout | /bin pointing to /usr/bin | Old paths keep working |
| Atomic releases | current pointing to a release directory | Switch versions in one rename |
| Enabled configuration | sites-enabled entries pointing to sites-available | Enable or disable without copying |
| Dotfile management | ~/.bashrc pointing into a versioned repository | Configuration kept under version control |
For deployments, the safe pattern is to create a new link under a temporary name and rename it over the old one with `mv -T`. A rename is atomic, so requests never see a moment without a valid link, whereas deleting and recreating the link leaves a short gap.
Permissions, security and pitfalls
On Linux, the permission bits of a symlink are always shown as 0777 and ignored. Access is decided entirely by the permissions of the target and of every directory along the resolved path; chmod on a link changes the target.
- Symlink attacks in shared directories: an attacker can place a link in
/tmppointing to a sensitive file; thefs.protected_symlinkssetting, enabled on most distributions, blocks following such links in sticky world-writable directories. - Absolute versus relative targets: absolute targets break when a directory tree is moved or mounted elsewhere; relative targets survive moves of the whole tree.
- Backups that follow links: copying with link following can duplicate large trees or escape the intended directory.
- Recursive deletion:
rm -ron a link removes the link, but a trailing slash can make some tools act on the target directory. - Loops: a link chain pointing back to itself produces
ELOOPerrors.
Programs that handle untrusted paths should open files with flags such as O_NOFOLLOW or resolve paths with controlled lookup functions, so that a planted link cannot redirect a privileged write.
Stripped to the essentials
A symbolic link is a signpost inside the file system. It is not the file itself; it only says where the real file can be found. When a program reaches the signpost, the system quietly walks it to the real place.
This makes it easy to give one file several convenient names or to point a familiar name at a new version. The catch is simple: if the real file is moved or deleted, the signpost points nowhere and the link stops working.
Where it is applied
A web team deploys each release of its application into a new directory such as /srv/app/releases/2026-11-10. The web server configuration always points to /srv/app/current, which is a symbolic link to the active release.
To deploy, the pipeline unpacks the new release, runs checks, creates a link named current.tmp to the new directory and renames it over current with mv -T. Because the rename is atomic, every request sees either the old or the new release, never a half-copied state.
When a problem appears, rolling back takes one command that points current at the previous release directory. A rollback completes in seconds, and older releases are deleted only after several successful deployments.