ln
Overview
ln creates links: hard links (default) or symbolic links (-s). Symlinks are path pointers and can cross filesystems and point at directories. Hard links are additional directory entries for the same inode, must stay on one filesystem, and generally cannot link directories on Linux.
Syntax
ln [options] target link_name
ln [options] target... directory
ln [options] -t directory target...Common Options
| Option | Description |
|---|---|
-s, --symbolic |
Create a symbolic link |
-f, --force |
Remove existing destination files |
-i, --interactive |
Prompt before removing destination |
-n, --no-dereference |
Treat link_name as a normal file if it is a symlink to a dir |
-v, --verbose |
Verbose |
-r, --relative |
Create symlink with relative target path (GNU) |
-T |
Always treat link_name as a normal file |
-t DIR |
Directory to place links into |
-b |
Backup destination before overwrite |
Hard vs symbolic
| Property | Hard link | Symlink |
|---|---|---|
| Cross filesystem | No | Yes |
| Point to directory | No (normal Linux) | Yes |
| Broken if target removed | Still has data if any link remains | Becomes dangling |
| Relative semantics | N/A (inode) | Stored path can be relative or absolute |
ls -l |
Same inode, no -> |
Shows -> target |
Examples with Explanations
Symbolic links
ln -s /usr/bin/python3 /tmp/py
ln -s ../config/app.yml .
ln -sfn /opt/app/releases/1.2 /opt/app/current # atomic-ish switch-f replaces; with symlinks to dirs, combine carefully with -n/-T to avoid nesting into the old dir.
Relative symlink (GNU)
ln -sr /opt/app/shared/.env /opt/app/current/.envStores a relative path from link location to target — friendlier when trees move together.
Hard links
ln file.txt file-hard.txt
ls -li file.txt file-hard.txt # same inodeBulk into a directory
ln -s /usr/bin/python3 /usr/bin/pip3 ~/bin/
ln -t ~/bin -s /usr/local/bin/appInspect
ls -l link
readlink link
readlink -f link
stat link
namei -l /path/to/linkReplace symlink safely
ln -sfn /opt/app/releases/1.3 /opt/app/current
# or
ln -s /opt/app/releases/1.3 /opt/app/current.new
mv -Tf /opt/app/current.new /opt/app/currentCommon failure: relative target confusion
cd /tmp
ln -s file.txt link # target is string "file.txt" relative to link’s directoryIf you create the link elsewhere, a relative target resolves from the link’s directory, not your cwd at creation time (you stored a string).
Notes / Pitfalls
ln -s existing_dir namewhennameexists as directory may createname/existing_dir— use-T/-nand check.- Hard links to shared libraries/configs can confuse package upgrades; prefer symlinks for admin sugar.
- Backup tools and containers may treat hard links specially (
rsync -H). - Dangling symlinks are valid entries; tools may or may not follow them.
- Permissions on a symlink are largely ignored on Linux; the target’s mode matters for access through the link.
2026-relevant notes
- Blue/green deploys still use
currentsymlink switches extensively. - Special filesystems (overlay, FUSE) may restrict hard links.
- Prefer
ln -sfnpatterns carefully; test once in a throwaway path.
Additional Resources
man ln