Skip to content

File system

The Filesystem Hierarchy Standard defines where things live on a Linux system. Packages follow it, so knowing it is how to predict where a file will be. The full standard is summarised on Wikipedia; the directories that matter to a software engineer are these.

/opt/ holds optional application software installed as a self-contained tree, typically by something other than the distribution’s package manager — a vendor tarball, a JetBrains IDE, a Gradle distribution.

/opt/
├── containerd
├── google
└── gradle

/usr/bin/ holds the bulk of the system’s command binaries: the ones provided by distribution packages and available to every user.

/usr/bin/
├── bash
├── cat
├── ls
├── ps
└── sh

/usr/local/bin/ holds commands installed by hand on this particular host, outside the package manager. Keeping them here rather than in /usr/bin/ is what stops a package upgrade from overwriting them.

/usr/local/bin/
├── docker-compose
└── idea

/etc/ holds host-specific, system-wide configuration. Nothing here should be a binary, and everything here is a candidate for version control.

/etc/opt/ holds configuration for the add-on packages installed under /opt.

/var/ holds data whose content changes during normal operation: logs, spool files, caches, queued mail. It is the directory that fills up.

/var/log/ holds the logs. On a systemd host the journal is here too, under /var/log/journal/, and is read with journalctl rather than with a text editor.

/var/opt/ holds the variable data of packages installed under /opt.

/proc/ is a virtual filesystem exposing process and kernel state as files — /proc/<pid>/ for a running process, /proc/meminfo and /proc/cpuinfo for the machine. Nothing here occupies disk.

/sys/ likewise exposes devices, drivers and kernel objects, and is where a running kernel’s tunables are read and written.

/dev/ holds device files: /dev/null, /dev/random, block devices such as /dev/sda1 and /dev/nvme0n1, and terminals such as /dev/tty.