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 |
PLACEMENT PRO TIP**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.
REMEMBER THIS**Remember:** Deleting a symlink with `rm` removes only the symlink, not the target. This is almost always what you want. To remove the target, you must `rm` the actual file or directory, not the symlink pointing to it.