Symbolic Link
A symbolic link (symlink) is a special file that contains a path pointing to another file or directory. Accessing the symlink transparently accesses the target. Unlike hard links, symlinks can cross filesystems and point to directories.
What Is a Symbolic Link in Simple Terms
A symbolic link is a shortcut — like a Windows shortcut or a macOS alias. It is a file that says "the thing you are looking for is actually over there." When you open the shortcut, the system transparently redirects you to the real thing.
The classic real-world use: a deployment system keeps the current version of an application at /opt/app/current. Instead of updating every config file when a new version is deployed, current is a symlink that gets updated to point to the new version directory.
How It Works
A symlink has its own inode. The data stored in its data block is just the target path as text — not the actual file content.
Symlink inode 9876+---------------------------+| Type: symlink (l) || Contents: /opt/app/v2.0/ |+---------------------------+ | | kernel follows path v/opt/app/v2.0/+---------------------------+| index.html || config.yaml || bin/ |+---------------------------+Hard link vs symbolic link comparison:
Hard Link Symbolic Link+-----------------------------++-----------------------------+| Same inode as target || Own inode || Link count increments || Link count unchanged || Cannot cross filesystems || Can cross filesystems || Cannot point to directory || Can point to directory || Works if target deleted || Breaks if target deleted || ls shows as regular file || ls shows as l, shows target |+-----------------------------++-----------------------------+Practical Commands
## Create a symbolic linkln -s /opt/app/v2.0 /opt/app/current## Now /opt/app/current -> /opt/app/v2.0 ## Create symlink to a fileln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite ## View symlinksls -la /opt/app/current## lrwxrwxrwx 1 root root 14 Jan 15 /opt/app/current -> /opt/app/v2.0 ## Read target pathreadlink /opt/app/current## /opt/app/v2.0 ## Resolve full absolute path (follows all symlinks)readlink -f /opt/app/current## /opt/app/v2.0 ## Update symlink to new version (atomic)ln -sf /opt/app/v3.0 /opt/app/current## -f forces overwrite. This is atomic -- no window where link is broken ## Find all symlinks in a directoryfind /etc -type l ## Find broken symlinks (target does not exist)find /etc -xtype l ## Remove a symlink (NOT the target)rm /opt/app/current## orunlink /opt/app/current ## Check if a path is a symlink in a scriptif [ -L /opt/app/current ]; then echo "It is a symlink"fiProduction deployment pattern:
## Deploy new version without downtimeSEMVER="v3.0.1" ## Step 1: Extract new versiontar xzf app-${SEMVER}.tar.gz -C /opt/app/ ## Step 2: Run database migrations, build steps, etc./opt/app/${SEMVER}/scripts/migrate.sh ## Step 3: Atomically update the symlinkln -sf /opt/app/${SEMVER} /opt/app/current ## systemd service points to /opt/app/current/bin/server## Reloading the service now uses the new versionsystemctl reload myapp ## Rollback: just point current back to previous versionln -sf /opt/app/v2.9.0 /opt/app/currentsystemctl reload myappTroubleshooting
| Symptom | Command | What to Look For |
|---|---|---|
| Symlink not working | readlink -f symlinkname |
Target path does not exist |
| Circular symlink | readlink -f symlinkname |
Output: Too many levels of symbolic links |
| Broken symlinks in /etc | find /etc -xtype l |
Lists all broken symlinks |
| ls shows wrong size for symlink | stat symlinkname |
Size shown is length of path string, not target |
Tip
ln -sf(symbolic, force) is the safest way to update a symlink. It atomically replaces the existing symlink in a single syscall. There is no window where the symlink does not exist, which means services reading through the symlink are never interrupted.
RememberDeleting a symlink with
rmremoves only the symlink, not the target. This is almost always what you want. To remove the target, you mustrmthe actual file or directory, not the symlink pointing to it.
Frequently Asked Questions
What actually breaks if I delete the file a symlink points to?
The symlink itself still exists as a file containing that now-invalid path, but following it returns 'No such file or directory' — this is called a dangling or broken symlink. This is different from a hard link, where the underlying data isn't actually freed until every hard link to it is removed, because hard links point to the same inode rather than to a path string.
When should you use a symlink instead of a hard link, and what's the common gotcha?
Use a symlink when you need to link across filesystems, link to a directory, or want the link to obviously break if the target moves (useful for versioned release directories like `current -> releases/v1.2.3`, a common blue-green deploy pattern). The gotcha: relative symlinks resolve relative to the symlink's own location, not your current working directory, which trips people up when a symlink is moved or accessed from a different path than expected.