Linux filesystem hierarchy notes
I know /etc and /var but get fuzzy on /usr/local vs /opt vs /usr, or on where a given application actually puts its runtime files. This is my cheat sheet for that, plus notes on how modern Debian differs from the FHS spec in a few places.
/etc — system-wide configuration
Configuration files for system software. These are text files, meant to be edited by admins. The name historically stands for "et cetera" but is better remembered as "everything to configure."
- Package installs drop their default configs here
- Local changes go in
.d/subdirectories where supported (e.g./etc/ssh/sshd_config.d/,/etc/apt/sources.list.d/) - Use drop-ins rather than editing package files directly — upgrades won't clobber your changes
- Worth putting under version control:
etckeeperdoes this automatically with git
/var — variable data
Data that changes during normal operation. Key subdirectories:
/var/log/— log files.journalctlcovers systemd services; traditional syslog writes here too./var/lib/— persistent application state. Database files, package manager state (/var/lib/dpkg/), etc./var/cache/— cached data that can be regenerated. APT's downloaded .deb files live in/var/cache/apt/archives/and can be safely cleared withapt clean./var/spool/— queued data: print jobs, mail, cron jobs./var/tmp/— temporary files that should persist across reboots. Unlike/tmp, not cleared on boot.
/tmp — ephemeral temporary files
On modern Debian, /tmp is usually a tmpfs mount — lives in RAM,
cleared on reboot. Size is typically half of RAM. Good for short-lived working
files; use /var/tmp/ if you need something to survive a reboot.
# Check if /tmp is tmpfs
mount | grep /tmp
# or
findmnt /tmp
/usr — installed programs and data
The bulk of installed software. Originally "user" but now effectively "Unix System Resources." Should be read-only after install.
/usr/bin/— user-facing executables/usr/sbin/— system/admin executables/usr/lib/— libraries and internal executables/usr/share/— architecture-independent data: docs, icons, locale files/usr/include/— C/C++ header files for development
On Debian 12+, /bin, /sbin, and /lib
at the root are now symlinks into /usr/. The merged-usr layout
simplifies things but can surprise older scripts that assume they're separate.
/usr/local — locally installed software
For software installed outside the package manager — compiled from source,
manual installs, scripts you wrote. Has the same structure as /usr/:
bin/, lib/, share/, etc.
Package-managed software should not touch /usr/local/, so it's a
clean separation. When I install something manually, it goes here.
/opt — self-contained third-party packages
For software that bundles all its own dependencies and doesn't integrate with
the system package layout. Each package gets its own subdirectory:
/opt/myapp/ with its own bin, lib, etc. inside.
In practice: vendor-supplied software that ships as a tarball with its own directory structure. Also common for things installed by snap or flatpak on desktop systems (though those have their own locations).
/run — runtime data
Replaces the old /var/run/ (which is now a symlink). PID files,
sockets, and other runtime state that should be cleared on boot. It's a tmpfs
so it's always in RAM.
# Common things in /run
ls /run/
# sshd.pid, systemd/, nginx/, fail2ban/, etc.
/proc and /sys — kernel interfaces
Both are virtual filesystems — no actual data on disk.
/proc/ exposes kernel and process information. Each running
process has a directory at /proc/<pid>/ with its file
descriptors, memory maps, etc. Also the home of /proc/sys/
for kernel tunables (adjustable via sysctl).
/sys/ (sysfs) exposes the kernel's view of hardware and
drivers. More structured than /proc. Most useful for hardware info and
driver parameters.
# Common /proc lookups
cat /proc/cpuinfo
cat /proc/meminfo
cat /proc/net/dev # network stats
# sysctl tunables
sysctl -a | grep net.ipv4.tcp
sysctl net.ipv4.ip_forward # check if IP forwarding is on
sysctl -w net.ipv4.ip_forward=1 # set live
Finding where things live
# Which package owns a file
dpkg -S /usr/sbin/nginx
# All files installed by a package
dpkg -L nginx
# Find a command's actual location
which nginx
command -v nginx # better in scripts
# Find files by name under a path
find /etc -name "nginx.conf"
# Find recently modified files (last 24h)
find /var/log -mtime -1 -type f