# ln — Create Hard Links and Symlinks

> Make links between files — create hard links and symbolic (soft) links to files and directories, giving one file multiple names or shortcuts.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/ln/

<!-- PROSE:intro -->
ln creates links between files – either a symbolic link (symlink) that points to a path like a shortcut, or a hard link, where multiple names reference the same inode and therefore the same data. The biggest gotcha is argument order: it is always `ln -s <target> <link>`, that is the target first and the name of the new link second – swap them and you create the link in the wrong place. This guide covers symlinks and hard links, the crucial difference between them, and common patterns such as atomic deployments and dotfile management.
<!-- PROSE:intro:end -->

## Symbolic Links (Soft Links)

`ln -s <target> <link>` — Create a symbolic link pointing to target.

```bash
ln -s /var/log/syslog ~/syslog
```

`ln -s <target>` — Create a symlink in the current directory with the same name as target.

```bash
ln -s /etc/nginx/nginx.conf
```

`ln -sf <target> <link>` — Create or overwrite a symbolic link (force).

```bash
ln -sf /usr/bin/python3.12 /usr/bin/python3
```

`ln -sn <target> <link>` — Do not dereference link if it is a symlink to a directory. Useful for replacing directory symlinks.

```bash
ln -sfn /var/www/release-2.0 /var/www/current
```

`ln -s <target1> <target2> <dir>` — Create multiple symlinks in a target directory.

```bash
ln -s /opt/bin/app1 /opt/bin/app2 /usr/local/bin/
```

## Hard Links

`ln <target> <link>` — Create a hard link. Both names point to the same inode and data.

```bash
ln important.txt important-backup.txt
```

`ln <target>` — Create a hard link in the current directory with the same name.

```bash
ln /data/shared-config.txt
```

`ln <target1> <target2> <dir>` — Create hard links to multiple files in a target directory.

```bash
ln file1.txt file2.txt /backup/
```

`ln -f <target> <link>` — Force creation by removing existing destination file.

```bash
ln -f newdata.txt data.txt
```

## Hard Links vs Symbolic Links

`ln <target> <link>` — Hard link: same inode, same filesystem only, survives target rename/move.

```bash
ln original.txt hardlink.txt
```

`ln -s <target> <link>` — Symbolic link: separate inode, cross-filesystem, breaks if target is removed.

```bash
ln -s original.txt symlink.txt
```

`ls -li <file>` — Show inode number. Hard links share the same inode as their target.

```bash
ls -li original.txt hardlink.txt
```

`stat <file>` — Show detailed file info including inode and hard link count.

```bash
stat original.txt
```

## Options

`ln -v <target> <link>` — Verbose mode. Print each link as it is created.

```bash
ln -sv /opt/app/config.yml ~/config.yml
```

`ln -i <target> <link>` — Interactive mode. Prompt before overwriting existing files.

```bash
ln -si /new/target existing-link
```

`ln -b <target> <link>` — Create a backup of existing destination file before overwriting.

```bash
ln -sb /new/target existing-link
```

`ln -S <suffix> <target> <link>` — Set backup suffix (default: ~) when using -b.

```bash
ln -sb -S .bak /new/target existing-link
```

`ln -r -s <target> <link>` — Create a relative symbolic link instead of absolute.

```bash
ln -rs /var/www/shared/assets /var/www/app/assets
```

`ln -t <dir> -s <target>` — Specify the link directory explicitly with -t.

```bash
ln -t /usr/local/bin -s /opt/app/bin/tool
```

## Managing Links

`readlink <link>` — Print the target of a symbolic link.

```bash
readlink /usr/bin/python3
```

`readlink -f <link>` — Print the fully resolved absolute path (follows all symlinks).

```bash
readlink -f /usr/bin/python
```

`ls -l <link>` — Show symlink target in long listing format (-> target).

```bash
ls -l /usr/bin/python3
```

`file <link>` — Show whether a path is a symlink and where it points.

```bash
file /usr/bin/python3
```

`unlink <link>` — Remove a symbolic or hard link (does not affect target).

```bash
unlink ~/syslog
```

`rm <link>` — Remove a link. Same as unlink for single files.

```bash
rm ~/syslog
```

`find . -type l` — Find all symbolic links in the current directory tree.

```bash
find /etc -type l
```

`find . -xtype l` — Find broken symbolic links (target does not exist).

```bash
find /usr/local/bin -xtype l
```

## Common Patterns

`ln -sfn <release-dir> <current>` — Atomic deployment: switch a symlink to a new release directory.

```bash
ln -sfn /var/www/releases/v2.1 /var/www/current
```

`ln -s /path/to/dotfile ~/.dotfile` — Dotfile management: symlink config files from a central repo.

```bash
ln -s ~/dotfiles/.vimrc ~/.vimrc
```

`ln -s $(which <cmd>) /usr/local/bin/<alias>` — Create a command alias via symlink.

```bash
ln -s $(which python3) /usr/local/bin/python
```

`for f in <dir>/*; do ln -s "$f" .; done` — Create symlinks to all files in a directory.

```bash
for f in /opt/config/*; do ln -s "$f" .; done
```

`ln -s /dev/null <file>` — Suppress a file by pointing it to /dev/null (e.g. unwanted logs).

```bash
ln -sf /dev/null ~/.bash_history
```

`find . -type l ! -exec test -e {} \; -print` — Find and list all broken symlinks.

```bash
find /usr/local -type l ! -exec test -e {} \; -print
```

`find . -maxdepth 1 -type l -delete` — Remove all symlinks in the current directory (non-recursive).

```bash
find . -maxdepth 1 -type l -delete
```

<!-- PROSE:outro -->
## Conclusion

ln is small but powerful – the key is keeping the two link types apart: a symlink (`-s`) is merely a reference to a path, works across filesystem boundaries, but breaks when the target disappears; a hard link is an equal second name for the same data, stays valid even after the target is renamed, but is confined to one filesystem and is not allowed for directories. Remember the argument order `ln -s <target> <link>`, and use `-sfn` to atomically switch directory symlinks (the classic deployment trick). When in doubt about what points where, check the inode and link count with `ls -li` and `stat`.

## Further Reading

- [GNU coreutils: ln invocation](https://www.gnu.org/software/coreutils/manual/html_node/ln-invocation.html) – official reference for every option
- [Linux man page: ln(1)](https://man7.org/linux/man-pages/man1/ln.1.html) – the canonical manual page
<!-- PROSE:outro:end -->

## Related Commands

- [cp](https://www.jpkc.com/db/en/cheatsheets/files-text/cp/) – copy files and directories
- [ls](https://www.jpkc.com/db/en/cheatsheets/files-text/ls/) – list directory contents and inodes
- [stat](https://www.jpkc.com/db/en/cheatsheets/files-text/stat/) – show detailed file and inode information

