open atlas
↑ Back to track
Linux, the operating system LIN · 01 · 03

The filesystem hierarchy

Linux has one filesystem tree rooted at /. The Filesystem Hierarchy Standard assigns a purpose to each top-level directory: /etc for config, /var for mutable state, /proc and /sys for live kernel data. Everything — including devices and kernel tunables — is a file.

LIN Junior ◷ 21 min
Level
FoundationsJuniorMiddleSenior

On Windows you have C:\, D:\, C:\Program Files, C:\Users. On Linux there is exactly one tree, rooted at /. Everything — disks, USB drives, network shares, running processes, and kernel configuration knobs — appears as a file somewhere in that tree. A network card is a file in /dev. The list of running processes is a directory in /proc. A kernel tunable for TCP buffer sizes is a file in /proc/sys/net. Once you know where things live in the tree and why, you know where to look when anything on the system is misbehaving.

Goal

After this lesson you can navigate the major top-level directories, explain what belongs in /etc, /var, /usr, /proc, /sys, /dev, and /home, and use the “everything is a file” model to read live system state from /proc.

1

One tree, everything mounted into it. Linux has a single namespace rooted at /. Additional disks, partitions, and network filesystems are mounted at specific paths inside the tree — they do not get drive letters. A second disk might be mounted at /mnt/data; a USB drive at /media/alice/usb. From the perspective of every program, there is only one filesystem.

This design comes from Unix: “everything is a file.” Not metaphorically — the kernel exposes hardware devices, inter-process communication endpoints, and its own internal state as entries in the filesystem namespace. Reading /dev/sda gives you raw disk bytes. Reading /proc/1/status gives you information about PID 1. Writing to /sys/block/sda/queue/scheduler changes the disk I/O scheduler at runtime.

2

/etc — static configuration. “et cetera” historically, now the canonical location for system-wide configuration files. Programs read from /etc at startup; they do not write to it during normal operation.

ls /etc | head -20
cat /etc/hostname          # the machine's hostname
cat /etc/os-release        # distro identity
cat /etc/resolv.conf       # DNS resolver configuration
ls /etc/systemd/system/    # systemd unit files you added

The rule: if you are editing how a daemon behaves, you are editing a file in /etc. If a config file is missing from /etc, the daemon falls back to compiled-in defaults.

3

/var — variable (mutable) state. Everything that changes during normal operation lives here: logs, mail spools, package databases, caches, lock files.

ls /var/log/               # system and application logs
ls /var/lib/               # persistent application state (dpkg db, containers)
ls /var/cache/             # cached data that can be regenerated
ls /var/run/               # (symlink to /run) PID files, sockets
tail -f /var/log/syslog    # follow the system log live

The practical consequence: if a disk is filling up, /var/log is often the culprit. If a service fails to start because it “can’t acquire lock”, the lock file is usually in /var/run or /var/lock. Separating /var onto its own partition is a classic server hardening technique — so log growth cannot fill the root partition and crash the OS.

4

/usr — the installed programs. Short for “Unix System Resources” (not “user”). Contains the vast majority of installed software:

  • /usr/bin — user-facing executables (grep, vim, python3, nginx)
  • /usr/lib — shared libraries and private program data
  • /usr/share — architecture-independent data (man pages, locale files, icons)
  • /usr/local — software you compiled and installed yourself (not via the package manager)

The root-level /bin and /sbin are now typically symlinks to /usr/bin and /usr/sbin on modern distros (the “usr merge”). This simplifies bind mounts and container images.

which nginx                # /usr/sbin/nginx
ls -la /bin                # symlink → /usr/bin on modern Debian/Ubuntu
5

/proc and /sys — the kernel’s live window. These are virtual filesystems generated entirely in kernel memory — nothing is written to disk. Reading a file in /proc or /sys triggers a kernel function that assembles the data on demand.

cat /proc/cpuinfo          # CPU model, cores, features
cat /proc/meminfo          # RAM usage in bytes
cat /proc/loadavg          # system load averages
ls /proc/1/                # everything about PID 1 (systemd)
cat /proc/1/cmdline        # command line of PID 1
cat /proc/1/status         # state, memory, signals
cat /sys/block/sda/size    # disk size in 512-byte sectors

/dev holds device files. /dev/null discards everything written to it. /dev/urandom provides cryptographically secure random bytes. /dev/sda is the first SATA disk. Character and block device files are the mechanism by which user programs interact with hardware through the kernel’s device driver layer.

Worked example

Diagnose a disk-full condition without a GUI.

df -h                      # disk usage per mount point (human-readable)
du -sh /var/log/*          # size of each log directory
du -sh /var/cache/apt/     # apt package cache

The df output shows you which filesystem is full. If it is /var, then du inside /var/log finds the offenders. Common culprits: /var/log/journal (persistent systemd journal that was never configured with a size cap), rotated nginx logs that were never deleted, or apt’s package cache after many updates.

# Clean apt cache to reclaim space
sudo apt clean
# Vacuum the journal to keep only the last 500 MB
sudo journalctl --vacuum-size=500M

Both commands go through the kernel — apt clean deletes files in /var/cache/apt/archives, journalctl --vacuum-size deletes journal files in /var/log/journal. No magic: everything is a file, files have sizes, sizes add up.

Why this works

macOS also has a single-tree filesystem rooted at /, and some directory names are the same (/etc, /tmp, /usr). But the FHS is a Linux/GNU standard — macOS has its own conventions. macOS applications live in /Applications, user data in ~/Library, and there is no /var/log/syslog (use log show instead). When troubleshooting on macOS, the paths differ even when the concept is the same.

Common mistake

Never store application data directly in / or /usr — it will be overwritten by OS upgrades or package updates. The correct locations: config belongs in /etc, persistent state in /var/lib/<appname>, temporary files in /tmp (cleared on reboot) or /var/tmp (survives reboots). Applications that write into /usr create conflicts with the package manager and are a classic source of “it worked before the upgrade” bugs.

Check yourself
Quiz

You read the file /proc/1/status and see the memory usage of PID 1 (systemd). Which statement best describes what just happened?

Recap

Linux has a single filesystem tree rooted at /. The Filesystem Hierarchy Standard assigns meaning to each top-level directory: /etc for static config, /var for mutable state and logs, /usr for installed programs, /home for user data. /proc and /sys are virtual filesystems generated in kernel memory — reading them queries live kernel state. /dev exposes hardware as files. The principle “everything is a file” is not a metaphor: devices, processes, kernel tunables, and network interfaces all appear as paths in the tree and can be read or written with standard file I/O.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources1
expand
  1. 01

Trademarks belong to their respective owners. Editorial reference only.