The ln command in Linux

ln creates links: additional names for existing files. A symbolic link (symlink, ln -s) is a small pointer to a path — the everyday kind, used for "current version" pointers, config switching and putting tools on the PATH. A hard link is a second directory entry for the same underlying data; it only works within one filesystem and cannot point to directories.

How ln works

A filename is not the file. The file is the inode — the metadata plus data blocks — and names are directory entries pointing at it. A hard link is simply a second entry pointing at the same inode: both names are equally "the real file", the inode's link count says how many exist, and the data lives until the count hits zero. This is also why hard links cannot cross filesystems (inode numbers are per-filesystem) nor point at directories (the tree must stay a tree).

A symbolic link is a different creature: a tiny file whose content is a path, resolved fresh every time it is traversed. That indirection buys everything hard links cannot do — crossing filesystems, linking directories, pointing at things that do not exist yet — at the price of breakability: move or delete the target and the symlink dangles. The deploy-by-symlink pattern exploits the best of both: the switch of a symlink is one atomic rename, so "current" flips between releases with no intermediate state.

directory entries (names)notes.txtsame-file (hard link)inode #48211mode · owner · size · timeslinks: 2data blocksshortcut (symlink)contains a path: "notes.txt"rm deletes a NAME; data frees only when the link count reaches 0 and no process holds it open
The name is not the file: hard links are equal names for one inode; a symlink is a small file holding a path, resolved on access.

Syntax

ln [-s] TARGET LINK_NAME

Common options

OptionWhat it does
-sCreate a symbolic link (almost always what you want).
-fReplace the link if it already exists.
-nWith -f, treat an existing symlink to a directory as a file to replace (crucial for "current" pointers).
(none)Without -s, ln creates a hard link.

How to use ln: examples

$ ln -s /opt/app-2.4.1 /opt/app/current

The deployment classic: "current" always points at the active release; switching versions is one atomic link change.

$ ln -s ~/dotfiles/.vimrc ~/.vimrc

Keep real configs in a git repo and symlink them into place.

$ ln -sfn /opt/app-2.4.2 /opt/app/current

Update an existing "current" pointer safely: -f replaces, -n avoids descending into the old target.

$ ls -l /opt/app

Symlinks show as: current -> /opt/app-2.4.2, with type "l" in the first column.

$ readlink -f /opt/app/current

Resolve where a symlink ultimately points.

Real-world use cases for ln

Zero-downtime release switching

Deploys unpack into /opt/app/releases/2026-08-04/, and /opt/app/current is a symlink to the live one. Releasing = ln -sfn to the new directory: one atomic operation, instant rollback by pointing back. This pattern underlies Capistrano-style deployment everywhere.

Dotfiles under version control

Keep the real .vimrc, .gitconfig and .bashrc in a git repo and symlink them into $HOME. Every machine gets ln -s ~/dotfiles/.vimrc ~/.vimrc once, and from then on git pull updates your configuration everywhere.

Pro tips and common mistakes

Frequently asked questions about ln

What is the difference between a symbolic and a hard link?

A symlink stores a path and breaks if the target moves; it can cross filesystems and point at directories. A hard link is another name for the same data blocks: the file survives until every hard link is deleted, but links cannot cross filesystems or reference directories.

Why is my symlink broken?

Its target was moved or deleted, or the link was created with a relative path that only resolved from the original location. ls -l shows the stored target; readlink -f shows what it resolves to.

Which order do the arguments go in?

Same as cp: real thing first, new name second — ln -s target link_name. If you get it backwards you create a link named after your target sitting in the wrong place.

Related commands

ls

List the contents of a directory, with options for hidden files, long format, sorting and more.

cp

Copy files and whole directory trees, preserving attributes when needed.

find

Locate files anywhere in a directory tree by name, type, size, date — and act on them.

Want to build real fluency? The interactive course takes you through ln and every other essential command with guided, checked exercises.