opscape

Files and directories

ln

Make links between files, symbolic (-s) or hard.

ln [OPTION...] TARGET [LINK_NAME]

11 of 11 examples run in Debian 13.7 on 2026-10-31 · coreutils 9.7-3 · manual: ln(1)

A symbolic link (ln -s) is a tiny file that contains a path. Opening the link opens whatever that path points to. It can point to a directory, across filesystems, or to something that does not exist (a "dangling" link). Delete the target and the link breaks.

A hard link (ln without -s) is a second name for the same file: both names point to the same inode and are fully equal. The data is freed only when the last name is removed. Hard links cannot span filesystems and cannot point to directories.

The argument order matches cp: what exists first, the new name second. A relative symlink target is resolved from the directory the link lives in, not from where you ran ln, which is the source of most broken links.

Examples

A hard link survives deleting the other name

ln todo.txt tasks.txt
rm todo.txt
cat tasks.txt
output
buy milk
fix login bug
write tests
fix logout bug
deploy v2.4

Removing todo.txt only removed one name. The data stays as long as any name (or open file handle) refers to it.

A symlink breaks when its target goes away

ln -s notes.txt n
rm notes.txt
ls -l n
cat n
outputexit 1
lrwxrwxrwx 1 dev dev 9 Oct 31 20:20 n -> notes.txt
cat: n: No such file or directory

The link still exists and still says notes.txt, but there is nothing there, so reading it fails with "No such file or directory".

Relative targets are relative to the link

ln -s data/users.csv src/users.csv
cat src/users.csv
outputexit 1
cat: src/users.csv: No such file or directory

The link src/users.csv contains data/users.csv, which is looked up from src/, giving src/data/users.csv: broken. The fix is the next example.

Let ln compute the relative path

ln -sr data/users.csv src/users.csv
ls -l src/users.csv
head -2 src/users.csv
output
lrwxrwxrwx 1 dev dev 17 Oct 31 20:20 src/users.csv -> ../data/users.csv
id,name,email,dept,joined
1,Alice Moreau,alice@example.com,engineering,2021-04-12

-r (--relative) writes the target relative to the link's own directory, here ../data/users.csv, and the link works. Relative links keep working if the whole tree moves.

Creating a link over an existing file

ln -s notes.txt todo.txt
explain
outputexit 1
ln: failed to create symbolic link 'todo.txt': File exists

ln will not replace an existing file without being told to.

Repoint an existing symlink

ln -s logs/app.log current.log
ln -sfn logs/error.log current.log
ls -l current.log
output
lrwxrwxrwx 1 dev dev 14 Oct 31 20:20 current.log -> logs/error.log

-f removes the existing link first. -n matters when the old link points to a directory: without it, ln would create the new link inside that directory. -sfn is the standard way to switch a current link between releases.

Link several files into a directory

mkdir bin
ln -sr scripts/greet.sh scripts/backup.sh bin/
ls -l bin
output
total 1
lrwxrwxrwx 1 dev dev 20 Oct 31 20:20 backup.sh -> ../scripts/backup.sh
lrwxrwxrwx 1 dev dev 19 Oct 31 20:20 greet.sh -> ../scripts/greet.sh

With a directory as the last argument, each link is created inside it under the target's name. -r makes the targets correct relative to bin/.

Common pitfalls

  • Argument order: ln -s TARGET LINK. Swapping them (ln -s newname existing) fails with "File exists" or, worse, creates a link inside a directory.

  • ln -s ../file stores exactly that text; it is resolved from the link's directory later. When unsure, use ln -sr or an absolute path.

  • Tools differ on whether they follow links: rm link removes the link, cp link copies the target, find and du do not follow links unless told (-L).

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • ln -r (--relative) is a GNU option; macOS ln lacks it, so compute the relative path yourself.

  • BSD/macOS ln uses -h (or -n) where GNU uses -n to avoid descending into an existing directory link; -sfn works on both.

Options worth knowing

A selection, described in our own words. For the full list, see ln(1) or ln --help.

OptionWhat it does
-s, --symbolicMake a symbolic link instead of a hard link.
-f, --forceRemove an existing destination first.
-n, --no-dereferenceTreat an existing link to a directory as a file, not a place to create the link in.
-r, --relativeWith -s, store the target relative to the link's directory.
-i, --interactiveAsk before replacing an existing file.
-v, --verbosePrint each link created.
-bBack up an existing destination before replacing it.
-t, --target-directory DIRCreate the links in DIR.
-T, --no-target-directoryTreat LINK_NAME as a name, never a directory.
-L, --logicalFor a hard link to a symlink, link to its target.
-P, --physicalFor a hard link to a symlink, link to the symlink itself.

Related