GICT knowledge base
Linux Hard Links and Symlinks: Create, Inspect and Troubleshoot Safely
Published
A hard link is another directory entry for the same file on the same filesystem. A symbolic link is a separate object storing a path. Neither is a private copy or an independent backup. This guide incorporates the overlapping ln-command and hardlink-versus-symlink articles while retaining their useful examples and failure cases.
See the difference on disposable data
Use a fresh temporary directory. The following sequence creates only synthetic files and does not overwrite an existing website or system link:
lab=$(mktemp -d) || exit 1
cd "$lab" || exit 1
printf 'content v1\n' > original.txt
ln -- original.txt hardlink.txt
ln -s -- original.txt symlink.txt
stat -c '%d:%i links=%h %n' -- original.txt hardlink.txt
readlink -- symlink.txt
cat -- hardlink.txt symlink.txt
The first two names have equal device/inode identities and a link count of two. Inode numbers are not fixed expected output, and file sizes depend on the bytes actually written. The symlink stores original.txt, and both reads currently reach the same data. Compare these relationships rather than expecting an old sample’s numeric inode or byte-count listing.
Remove one name, not the shared data
Continue only in the temporary directory created above:
rm -- original.txt
cat -- hardlink.txt
test -L symlink.txt && printf 'symlink still exists\n'
if test -e symlink.txt; then
printf 'target resolves\n'
else
printf 'target does not resolve\n'
fi
The hard link still reads content v1, while the symlink remains but dangles. File storage is not necessarily reclaimed immediately when the last name is removed: an open file description can keep an unlinked file alive. Writing in place through either hard-linked name modifies shared data; an editor that saves by replacing a pathname can instead create a different file.
Relative paths are valid
A relative symlink target is resolved from the link’s containing directory, not whichever directory the reader happens to use. Continue the fixture to demonstrate:
mkdir -- data links
printf 'relative target\n' > data/note.txt
ln -s -- ../data/note.txt links/note
cat -- links/note
find . -type l -print
find . -xtype l -print
The read succeeds. GNU find’s first list shows the symlinks; its second, without link-following options, identifies dangling ones in this fixture. Inspect candidates before removal. Do not append a blanket delete action to a home-directory or system-wide search.
Limits and practical choices
- Hard links cannot span filesystems and ordinary directory hard links are prohibited. Existing mount layouts and permissions can restrict creation even when a pathname looks nearby.
- Symlinks can point to directories or another mounted filesystem, but a missing mount, inaccessible path or moved target can make resolution fail.
- Inspect the link and target deliberately before changing ownership or modes. Ordinary Linux symlink mode bits are not a separate access gate for target data.
- Remove the intended link name, without a trailing directory slash; do not confuse the target path with the link path.
Deployments and backups
Some distribution layouts use links for enabled web-server sites, but this is not universal Apache/Nginx behavior. Use application-managed release pointers only with a tested deployment procedure; do not force-replace /usr/local/bin/python3 or existing dotfiles as a beginner example. Review whether backup/copy tools preserve links or follow targets.
Hard-linked backup snapshots can save space for unchanged files, but in-place writes can affect shared snapshot data. Treat retained snapshots as protected recovery material and verify restoration; neither a second hard-linked name nor a symlink protects against disk failure.
References: GNU ln and relative targets; Linux symbolic-link handling; unlink and open-file lifetime; GNU find link tests.
Reviewed October 15, 2026. The three exact example blocks were checked sequentially in an isolated Linux fixture, not on a customer filesystem or production deployment.
Related guides
How to Set Up zram on a Small VPS
Configure zram on Ubuntu with kernel and swap checks. Understand compressed memory limits, monitor real use and avoid unsafe swap-file changes.
LinuxHow to Find Services That Need a Restart After Updates with needrestart
Find services using outdated libraries with needrestart on Ubuntu. Read restart reports, review automatic restart policy and plan maintenance safely.
LinuxHow to Limit a Linux Service’s Memory with systemd
Limit a Linux service with systemd MemoryHigh, MemoryMax and swap controls. Check cgroup support, diagnose pressure and remove only your own policy.
LinuxHow to Protect SSH with CrowdSec on Ubuntu
Protect SSH with CrowdSec on Ubuntu. Connect log detection to firewall enforcement and test temporary blocking without losing administrator access.
