- Describe the purpose of each top-level directory defined by the Filesystem Hierarchy Standard
- Distinguish between directories that hold programs, configuration, data, and runtime state
- Explain why /proc, /sys, /dev, and /run are pseudo-filesystems rather than on-disk storage
- Locate common files and commands in their expected directories
- Apply FHS conventions when installing and configuring software
One of the first things a newcomer to Linux notices is the sprawling tree of directories under /, with cryptic names like /usr, /opt, /var, and /proc. Most of these names are historical, inherited from the earliest days of Unix, and the reasons behind them are not always obvious. But the layout is not arbitrary. It follows a document called the Filesystem Hierarchy Standard (FHS), and understanding it transforms Linux from a maze into a map.
Why There Is a Standard
In the 1990s, every Unix vendor had its own opinions about where things should live. Sun Solaris put system binaries in one place, HP-UX in another, IBM AIX in a third; Red Hat and Debian disagreed with each other and with everybody else. This made writing portable software a nightmare. In 1994, a group of Linux developers started working on a standard, and in 1997 the first version of the FHS was published. Today all mainstream distributions follow it with only minor deviations.
The FHS provides two kinds of guidance. First, it defines the purpose of each top-level directory — what goes where. Second, it encodes principles about how directories should be organised: static versus variable data, shareable versus host-specific data, things the system needs to boot versus things that can be mounted later.
The Root Directory
Everything on a Linux system starts at /, the root directory. Unlike Windows, which has multiple drive roots (C:\, D:\), Linux has exactly one root. Additional disks are mounted inside the existing tree, at directories like /mnt/backup or /media/usb.
ls /
# bin boot dev etc home lib lib64 media mnt opt
# proc root run sbin srv sys tmp usr var
Let us walk through each of these in turn.
/bin and /sbin — Essential Binaries
/bin holds the essential command binaries that every user needs: ls, cp, mv, rm, cat, echo, bash, and so on. These are the commands without which the system is unusable.
/sbin holds system binaries — commands reserved for the system administrator, like fdisk, mkfs, ifconfig, reboot, shutdown. On many modern distributions /sbin is just a symlink to /usr/sbin, and similarly /bin to /usr/bin. This merged-usr layout simplifies the FHS and is now the default on Fedora, Arch, and recent Debian.
/etc — Configuration
/etc is where system-wide configuration files live. The name is famously cryptic — it originally stood for "et cetera", a catch-all for miscellaneous files on early Unix systems — but today it is reserved for configuration.
Key files and directories include.
Configuration files in /etc are almost always plain text. This is a deliberate design choice. You can read them with less, edit them with any editor, version them with git, and diff them across machines. Compare this with Windows, where so much configuration lives in an opaque binary registry.
/home — User Data
Each ordinary user has a home directory under /home, typically /home/alice for the user alice. This is where personal files, configuration (in hidden dotfiles like .bashrc and .vimrc), and application data live. The environment variable $HOME and the shortcut ~ both refer to the current user's home directory.
echo $HOME
# /home/chris
cd ~
pwd
# /home/chris
The root user is an exception — its home lives at /root, directly off the root of the filesystem, so that it remains accessible even if /home (which is often on a separate disk partition) is unavailable.
/usr — The Secondary Hierarchy
/usr is the largest and most confusing part of the FHS. Despite the name — which originally meant "user" — it does not contain user data. It is a secondary hierarchy holding the majority of installed software.
ls /usr
# bin games include lib libexec local sbin share src
Within it:
/usr/bin— most of the system's installed commands/usr/sbin— administrative commands that are not essential at boot/usr/lib— libraries for the binaries in/usr/binand/usr/sbin/usr/include— C header files for development/usr/share— architecture-independent data (manual pages, icons, documentation)/usr/local— software installed locally by the administrator, not by the package manager/usr/src— source code, often the Linux kernel source
Why is there a /usr/bin when there is already a /bin? Historically, /usr was a separate partition that held the non-essential parts of the system. In the early 1970s, Ken Thompson's and Dennis Ritchie's PDP-11 had two small disks, and when the system partition filled up they moved user home directories — literally, /usr/ken and /usr/dmr — onto the second disk. When that disk too filled up, they moved bin, lib, and other system files onto it as well. The split between /bin and /usr/bin thus dates back to an accident of disk sizing more than half a century ago. The merged-usr transition is finally correcting it.
/var — Variable Data
/var holds variable data — files that change during normal system operation. Logs, mail spools, print queues, caches, and databases all live here.
ls /var
# backups cache crash lib local lock log mail opt run spool tmp
The most frequently visited subdirectory is /var/log, where system services record their activity. When something goes wrong, /var/log is usually the first place to look. /var/lib holds persistent application state (the databases of package managers, for example), and /var/cache holds cached data that can be regenerated if lost.
/tmp — Temporary Files
/tmp is for temporary files that programs create during their work. It is world-writable, but each file is owned by the user who created it. Files in /tmp are typically wiped at reboot (and on many systems, /tmp is in fact a tmpfs — a filesystem in RAM rather than on disk). Never store anything important in /tmp.
/opt — Optional Packages
/opt is a home for third-party software that ships as a self-contained package, usually from a commercial vendor. A product called Acme might install everything under /opt/acme — binaries, libraries, config, data — rather than scatter files across the FHS. This makes it trivial to remove: just delete /opt/acme.
/proc, /sys, /dev, /run — Pseudo-filesystems
Several directories do not correspond to on-disk storage at all. They are virtual filesystems generated by the kernel.
/proc exposes process and kernel information. Every running process has a directory /proc/<pid> containing metadata and file descriptors. Global files like /proc/cpuinfo and /proc/meminfo let you query kernel state.
/sys exposes the device model: the hierarchy of buses, devices, and drivers that make up the hardware. You can read or change many device parameters by reading and writing files under /sys.
/dev holds device files — special files that represent hardware devices. Reading from /dev/sda reads bytes from the first SATA disk; writing to /dev/null throws the data away; reading /dev/urandom gives you cryptographic random bytes.
ls -l /dev/null /dev/sda /dev/tty
# crw-rw-rw- 1 root root 1, 3 Apr 9 10:00 /dev/null
# brw-rw---- 1 root disk 8, 0 Apr 9 10:00 /dev/sda
# crw-rw-rw- 1 root tty 5, 0 Apr 9 10:00 /dev/tty
The c at the start of the permissions indicates a character device (byte-at-a-time) and b a block device (fixed-size blocks). The two numbers 1, 3 are the major and minor device numbers, which tell the kernel which driver to dispatch to.
/run is a relatively new addition (added around 2011) that holds runtime data — PID files, Unix sockets, and other state that services need while running but that should not survive a reboot. It is always a tmpfs in RAM.
/boot — Boot Files
/boot contains the files needed to start the system: the kernel image (vmlinuz), the initial ramdisk (initrd.img or initramfs.img), and the bootloader configuration (usually GRUB's /boot/grub/grub.cfg). On machines with UEFI, there is also an EFI System Partition mounted at /boot/efi.
ls /boot
# config-6.8.0-76-generic initrd.img-6.8.0-76-generic vmlinuz-6.8.0-76-generic
# grub System.map-6.8.0-76-generic
/root, /mnt, /media, /lib, /srv
/root— the home directory of therootuser/mnt— a traditional mount point for temporarily-mounted filesystems, used by the administrator/media— automatic mount points for removable media (USB drives, DVDs)/lib— essential shared libraries needed by/binand/sbin(often a symlink to/usr/lib)/srv— data served by the system (e.g./srv/wwwfor a web server,/srv/ftpfor an FTP server)
Principles Behind the Layout
Two dimensions organise the FHS. The first is static versus variable: programs and libraries (/usr, /bin) rarely change, whereas logs and caches (/var) change constantly. This matters because static data can be mounted read-only, or shared over the network between machines, while variable data must be local and writable.
The second dimension is shareable versus unshareable. /usr is shareable — you could mount the same /usr on many machines of the same architecture — while /etc is unshareable, because each machine has its own configuration.
| Shareable | Unshareable | |
|---|---|---|
| Static | /usr, /opt |
/etc, /boot |
| Variable | /var/mail, /var/spool/news |
/var/log, /var/run |
This matrix is a useful way to think about where new things should go if you ever write software that needs to create files on a Linux system.
Finding Your Way Around
The two commands you will use most often for navigation are cd (change directory) and ls (list directory). A few tricks:
cd # return to home
cd - # return to previous directory
cd .. # go up one level
ls -l # long listing
ls -la # include hidden files
ls -lh # human-readable sizes
Spend a few minutes wandering your filesystem. Read /etc/os-release to see what distribution you are on. Look at /proc/cpuinfo to see your CPUs. Count how many files are in /usr/bin. The FHS is not just bureaucracy — it is a map of the operating system, and once you know it, you will never feel lost on a Linux machine again.