On a current Linux distribution, `ls -ld /bin` shows that /bin is a symbolic link to usr/bin. What is the "/usr merge", why was it done, and what does it change in practice?
answer
- one tree instead of two
- the initramfs took over early boot
- old paths still resolve through symlinks
- /usr becomes shareable and verifiable
- string-comparing paths gets unreliable
basics
~20 sThe /usr merge turns /bin, /sbin, /lib and /lib64 into symbolic links into /usr, so every program and library has exactly one real location. It removes a split that only existed so a tiny root filesystem could mount a separate /usr, a job the initramfs now does.
solid answer
~40 sHistorically the root filesystem carried a minimal tool set in `/bin`, `/sbin` and `/lib` — just enough to boot and mount `/usr`, which often lived on a separate, larger or network-mounted disk. Once every distribution booted through an initramfs, that early tool set moved into the initramfs and the split lost its purpose, while the question "is this binary in /bin or /usr/bin?" stayed as pure noise. The merge makes `/bin`, `/sbin`, `/lib` and `/lib64` symlinks into `/usr`, so all shipped code lives under one tree. Old paths keep working through the symlinks, so `#!/bin/sh` is fine. The payoff is that `/usr` becomes a single, self-contained, read-only-mountable, snapshot- and signature-friendly unit — the basis for image-based and atomic-update systems. Fedora did this in Fedora 17; Debian completed it in Debian 12.
code
bash · 3 linesls -ld /bin /sbin /lib
# both names resolve to the same file after the merge
readlink -f /bin/ls /usr/bin/lsgo deeper
Recognise that /bin, /sbin and /lib are symlinks into /usr on current systems, and that old paths like /bin/sh still work. Do not be alarmed when two paths name the same binary.
Explain the historical reason for the split — bootstrapping a separate /usr — and why the initramfs made it obsolete. Describe the concrete result: one tree, compatibility symlinks, relative link targets.
Connect it to operations: a merged /usr can be mounted read-only, snapshotted, shared and verified as a unit, which underpins image-based systems; and know the failure modes, including split-/usr without an initramfs and path-string comparisons that silently mismatch.
Frame it as the enabling step for immutable, atomically updated systems, and be able to reason about the migration cost a fleet pays: package path conflicts, tooling that assumes fixed locations, and the ordering guarantees a distribution had to provide across several releases.
## What the split was for Early Unix systems put the essential tools in `/bin`, `/sbin` and `/lib` on the root filesystem, and everything else in `/usr`, which was frequently a separate partition — sometimes on another disk, sometimes NFS-mounted and shared between machines. The rule was: root must contain enough to boot the machine, run `fsck`, and mount `/usr`. Everything else could wait. That produced the categorisation nobody could ever remember. Why is `mount` in `/bin` but `mkfs` in `/sbin`? Why is `less` in `/usr/bin` but `more` in `/bin`? The answers are archaeological, not logical: they record which tool somebody once needed before `/usr` was available. ## What made it obsolete The initramfs. Modern Linux boots by loading a compressed root filesystem image into memory alongside the kernel; that image contains the drivers, `udev`, and the tools needed to find and mount the real root — including, if the layout requires it, `/usr`. The early boot environment is therefore *not* the root filesystem any more, so the reason for keeping a duplicate tool set on root disappeared. At the same time a new requirement appeared from the other direction. If all shipped code lives in exactly one directory tree, then `/usr` can be: - mounted read-only, with `/etc` and `/var` as the only writable state; - shared between machines or containers, or shipped as an image; - snapshotted and rolled back as a unit; - verified as a unit, e.g. with a dm-verity hash tree over the whole tree. None of that works if half the operating system is scattered across the root directory. ## What the merge actually does The change is deliberately minimal — nothing is deleted, and no path stops working: ``` /bin -> usr/bin /sbin -> usr/sbin /lib -> usr/lib /lib64 -> usr/lib64 ``` Note that the targets are *relative* (`usr/bin`, not `/usr/bin`), which keeps them correct when the tree is inspected from a chroot or a mounted image rather than as the live root. Because the symlinks remain, `#!/bin/sh`, `#!/bin/bash` and `/usr/bin/env` all continue to resolve, and a script written in 1995 still runs. Packages install into the `/usr` paths; the compatibility symlinks catch everything that still asks for the old ones. Some distributions have taken a further step and merged `/usr/sbin` into `/usr/bin`, dissolving the administrative/ordinary split as well: Debian did this in Debian 13 (trixie), and Fedora has made the same change in recent releases. ## What actually changes for you 1. **Path comparison stops being reliable.** Two paths can name the same file. Code that compares the output of a lookup against a hardcoded string — `if [ "$(command -v foo)" = /usr/bin/foo ]` — can be wrong through no fault of its own. Compare inodes or resolved paths, not strings. 2. **Two names, one file.** A tool that reports "the binary is at /bin/ls" and another that reports `/usr/bin/ls` are not disagreeing. Symlink resolution, not a discrepancy. 3. **Packaging conflicts were the hard part.** During the transition, the risk was that one package claimed `/bin/foo` while another claimed `/usr/bin/foo` — the same file under two names, which package tooling could see as a conflict or, worse, unpack in an order that removed a live binary. This is why distributions treated the merge as a multi-release project with dedicated conversion tooling rather than flipping a switch. 4. **A split /usr is no longer supported.** With the merge, mounting `/usr` from a separate filesystem *without* an initramfs cannot work: the symlinks point into a tree that is not there yet. Distributions state this outright — an initramfs (or `/usr` on the root filesystem) is required. 5. **You still cannot assume a path.** The merge did not standardise *which* names exist; it only removed the duplication. Interpreters still differ across distributions, which is why `#!/usr/bin/env python3` remains the portable form. ## The interview point The fact to state is not "/bin is a symlink now". It is *why*: the historical split existed to bootstrap a separate `/usr`, the initramfs took over that job, and collapsing the tree turns `/usr` into a single immutable unit that can be shared, snapshotted, verified and shipped. That framing connects a piece of Linux trivia to how image-based and container systems are built.
- Does the merge break a script whose shebang is #!/bin/sh?No. `/bin` remains as a symbolic link to `usr/bin`, so the kernel resolves `/bin/sh` exactly as before. Nothing was deleted; the merge only removed the duplicate storage locations while keeping every historical name valid. What can break is code that *compares* paths as strings, since one file now legitimately answers to two names.
- Why are the compatibility symlinks relative (usr/bin) rather than absolute (/usr/bin)?A relative link stays correct when the tree is examined somewhere other than as the running root — inside a chroot, a mounted disk image, an extracted container filesystem or an installer target. An absolute link would escape to the host's `/usr` instead of the tree you mounted, which is precisely the mistake image tooling must avoid.
- After the merge, can /usr still live on a separate filesystem?Yes, but only with an initramfs that mounts it before handing control to the real root. Since the root directory's `bin`, `sbin` and `lib` now point into `/usr`, a root filesystem without `/usr` mounted has essentially no working userspace. Distributions state the initramfs requirement explicitly rather than supporting the old split-boot path.
saying these in an interview costs you the question
- Says /bin was deleted so old shebangs are broken
- Thinks the merge was purely cosmetic tidying
- Claims /usr can still be split off without an initramfs
- Treats /bin/ls and /usr/bin/ls as two different programs
- Compares command lookup output against a hardcoded path