What a symbolic link is
ln -s target name creates a small file name with a special flag that marks
it as a symlink, and with contents that are a path string pointing to target.
This is a separate inode, with its own permissions and timestamps.
When a program opens a symlink, the kernel dereferences it and works with
the target instead. Most syscalls are transparent (open, stat,
read/write). One that is not is lstat, which looks at the symlink itself
rather than the target.
Symlink vs hard link
| property | hard link | symbolic link |
|---|---|---|
| inode | same as the target | its own |
| works across filesystems | no | yes |
| works on directories | no | yes |
| survives target deletion | yes (contents stay alive) | no (becomes "broken") |
| size | 0 (nothing of its own) | path length in bytes |
shown as a "different file" in ls -li | inode matches | different inode plus "-> target" |
Broken links
If the target is deleted or renamed, the symlink stays but points nowhere:
ln -s /no/such/path slink
ls -l slink # shown red/italic in most terminals
cat slink # No such file or directory
To find every broken symlink in a tree:
find /path -type l -! -exec test -e {} \; -printWhere you see it
/usr/bin/python3→python3.12(versioned alternatives viaupdate-alternatives)/etc/localtime→/usr/share/zoneinfo/<TZ>- In systemd units:
/etc/systemd/system/multi-user.target.wants/*.service→/lib/systemd/system/*.service - Atomic deploys: the current version is a symlink to a specific release