Linux File System Hierarchy Explained

Linux File System Hierarchy Explained

Run ls / on any Linux system and you get a list that looks roughly the same whether you are on Ubuntu, Fedora, Arch, or Debian. The names are the same. The purpose of each directory is the same. That consistency is not accidental. It comes from the Filesystem Hierarchy Standard (FHS), a specification that defines what goes where and why.

Understanding the layout takes the mystery out of where things live, why configuration files are not next to binaries, and why some directories are virtual filesystems with no data on disk at all.

Everything starts at root

Linux has one filesystem tree. It starts at /, called the root directory. There are no drive letters, no C:\ or D:\. External drives, network shares, and additional partitions are all mounted as directories somewhere under /.

# See what is at the top of the tree
ls -1 /

# See what filesystems are mounted and where
findmnt --tree

# Check disk usage of top-level directories
du -sh /* 2>/dev/null | sort -h

Every absolute path on the system starts with /. A path like /etc/ssh/sshd_config means: start at root, go into etc, then ssh, then the file sshd_config.

The modern /usr merge

Before walking through each directory, one important piece of context: the traditional Linux directory layout had binaries split between the root (/bin, /sbin, /lib) and /usr (/usr/bin, /usr/sbin, /usr/lib). The historical reason was that early Unix systems had small root partitions and separate /usr partitions that mounted later in the boot process. Essential tools needed to boot had to live outside /usr.

Modern Linux distributions have merged these. On Fedora, Ubuntu, Debian, Arch, and most others, /bin, /sbin, and /lib are now symbolic links pointing into /usr:

ls -la /bin /sbin /lib
# lrwxrwxrwx 1 root root 7 /bin -> usr/bin
# lrwxrwxrwx 1 root root 8 /sbin -> usr/sbin
# lrwxrwxrwx 1 root root 7 /lib -> usr/lib

This means /bin/bash and /usr/bin/bash are the same file. The merger simplifies the layout and removes a class of boot-time complications. Keep this in mind when you read older documentation that treats /bin and /usr/bin as separate locations.

Directory by directory

/ (root)

The top of the tree. Only root-owned directories and a handful of symlinks live here. Regular users should never create files directly in /.

/usr - user system resources

Despite the name, /usr does not mean “user files.” It stands for Unix System Resources and contains the bulk of installed software. Think of it as the read-only shareable part of the system.

/usr/bin/       # user-facing executables (bash, ls, grep, git, python3...)
/usr/sbin/      # system administration executables (useradd, iptables...)
/usr/lib/       # shared libraries and internal executables
/usr/lib64/     # 64-bit libraries (on systems that separate them)
/usr/include/   # C/C++ header files for development
/usr/share/     # architecture-independent data (man pages, icons, locale data)
/usr/local/     # software installed manually outside the package manager

/usr/local/ deserves special attention. It mirrors the structure of /usr (with bin, lib, share subdirectories) and is where you put software you compile and install yourself with make install. Package managers do not touch /usr/local, so software there does not get overwritten on system updates.

/etc - system configuration

All system-wide configuration files live here. Text files, editable by an administrator. No binaries.

# Common files you will edit regularly
/etc/fstab          # filesystem mount table
/etc/hosts          # local hostname-to-IP mappings
/etc/hostname       # the machine's hostname
/etc/passwd         # user account database
/etc/shadow         # hashed passwords (root-readable only)
/etc/group          # group definitions
/etc/ssh/sshd_config  # SSH server configuration
/etc/apt/           # apt package manager configuration (Debian/Ubuntu)
/etc/systemd/       # systemd unit overrides and configuration
/etc/cron.d/        # cron job definitions
# Find recently modified config files
find /etc -newer /etc/passwd -type f 2>/dev/null | sort

# Check who last changed a config file
stat /etc/ssh/sshd_config

/var - variable data

Files that change during normal operation. Logs, caches, spools, runtime databases.

/var/log/       # log files (syslog, auth.log, nginx/access.log...)
/var/cache/     # package manager caches, app caches
/var/lib/       # persistent app state (databases, package manager data)
/var/spool/     # queued data (print jobs, mail, cron)
/var/tmp/       # temporary files preserved across reboots
/var/www/       # web server document root (by convention)

On production servers, /var/log is the first place to look when something breaks:

# Disk usage breakdown of /var/log
du -sh /var/log/* | sort -h | tail -20

# Watch logs from all services in real time
journalctl -f

# Logs from a specific service
journalctl -u nginx --since "1 hour ago"

# Traditional log files
tail -f /var/log/syslog
tail -f /var/log/auth.log

/var often lives on its own partition on servers so that a log flood cannot fill the root filesystem and crash the system.

/home - user home directories

Each regular user gets a subdirectory under /home. A user named alice has a home directory at /home/alice. This is where personal files, shell configuration (.bashrc, .bash_profile), and user-level application config live.

# Your home directory (shorthand)
echo ~
cd ~

# Config files in your home directory
ls -la ~ | grep '^\.'

# Shell configuration
cat ~/.bashrc
cat ~/.bash_profile   # or ~/.profile

# SSH keys
ls -la ~/.ssh/

On a server with no interactive users, /home may be nearly empty. On a multi-user workstation it can be the largest directory on the system.

/root - root user’s home

The root user’s home directory is /root, not /home/root. It is kept separate from /home so it is available even if the /home partition fails to mount.

/tmp - temporary files

Scratch space for any process that needs to write temporary data. Two key properties: files here are accessible by all users (with the sticky bit set, so users cannot delete each other’s files), and the directory is typically cleared at boot.

On most modern systems, /tmp is a tmpfs, meaning it lives in RAM rather than on disk:

# Check if /tmp is a tmpfs
df -h /tmp
mount | grep /tmp

# How much of /tmp is in use
du -sh /tmp

Because it is RAM-backed, /tmp is fast but limited in size. For large temporary files that need to survive a reboot, use /var/tmp instead.

/run - runtime data

A relatively recent addition to the FHS, /run holds runtime state for the current boot only. PID files, sockets, and lock files live here. It is a tmpfs cleared at every boot.

ls /run

# systemd puts socket files and runtime state here
ls /run/systemd/

# The SSH daemon's PID file
cat /run/sshd.pid 2>/dev/null

/var/run is now a symbolic link to /run on modern systems.

/proc - process and kernel information

A virtual filesystem. Nothing here is on disk. The kernel generates the content dynamically when you read a file.

# CPU information
cat /proc/cpuinfo

# Memory information
cat /proc/meminfo

# Kernel version
cat /proc/version

# Loaded kernel modules
cat /proc/modules

# Running processes: each PID has its own directory
ls /proc/ | grep '^[0-9]' | head -10

# Information about a specific process
ls /proc/$$/          # $$ is the current shell's PID
cat /proc/$$/cmdline  # command that started this process
cat /proc/$$/status   # process status and resource use

# Kernel tunable parameters
ls /proc/sys/kernel/
cat /proc/sys/kernel/hostname

/sys - kernel and hardware interfaces

Similar to /proc but more structured. /sys exposes kernel objects as a hierarchy: devices, drivers, buses, and power management.

# All block devices the kernel knows about
ls /sys/block/

# Information about a specific disk
ls /sys/block/sda/
cat /sys/block/sda/size

# CPU topology
ls /sys/devices/system/cpu/

# Power management settings
cat /sys/power/state

# Network interfaces
ls /sys/class/net/
cat /sys/class/net/eth0/speed 2>/dev/null

/sys is the interface used by tools like lspci, lsblk, lscpu, and udevd. You rarely edit files here directly, but understanding that /sys exists explains how those tools get their data.

/dev - device files

Every hardware device and many virtual devices are represented as a file under /dev. This is the Unix philosophy taken literally: everything is a file.

/dev/sda        # first SATA/SCSI disk
/dev/sda1       # first partition on that disk
/dev/nvme0n1    # first NVMe disk
/dev/tty        # the current terminal
/dev/null       # discards all input, reads return EOF
/dev/zero       # produces infinite null bytes
/dev/random     # cryptographically secure random bytes
/dev/urandom    # non-blocking random bytes
# Discard output entirely
command > /dev/null 2>&1

# Generate a 1 MB file of random data
dd if=/dev/urandom of=random.bin bs=1M count=1

# See block devices
lsblk

# See character and block devices in /dev
ls -l /dev | grep '^[bc]'

Device files are created and managed by udev, which runs as a daemon and responds to kernel events when hardware is plugged in or removed.

/boot - boot files

Kernel images, initramfs, and the bootloader live here.

ls /boot

# See installed kernels
ls /boot/vmlinuz*

# GRUB bootloader configuration
cat /boot/grub/grub.cfg

On systems using EFI, /boot/efi or a separate EFI System Partition (/efi) holds the bootloader files that the firmware reads.

/opt - optional software

Third-party software that does not follow the /usr layout is conventionally installed here. Each package gets its own subdirectory: /opt/google/chrome/, /opt/discord/, etc. Unlike packages installed via the distro’s package manager, /opt software manages its own internal layout.

/srv - service data

Data served by the system. A web server might serve files from /srv/www/. An FTP server might serve from /srv/ftp/. The convention is less universally followed than others in the FHS, but the intent is to give a clear location for externally-served content separate from system files in /var.

/mnt and /media - mount points

/mnt is a conventional location for temporarily mounting filesystems manually. When you mount an external drive or a network share for a one-off task, /mnt or a subdirectory of it is the right place.

/media is used by desktop environments and udisks for automounting removable media. When you plug in a USB drive, it typically appears at /media/username/drive-label/.

# Mount a USB drive manually
sudo mount /dev/sdb1 /mnt/usb

# Unmount it
sudo umount /mnt/usb

# See currently mounted filesystems
findmnt

A few commands that make the hierarchy easier to explore:

# Visual tree of a directory (install tree if not present)
tree /etc/ssh
tree -L 2 /usr

# Find a file by name anywhere on the system
find / -name "sshd_config" 2>/dev/null

# Find which package owns a file
dpkg -S /usr/bin/curl          # Debian/Ubuntu
rpm -qf /usr/bin/curl          # Fedora/RHEL

# Find where a command lives
which python3
type -a python3
whereis python3

# Show the full path of a relative file
realpath ~/.bashrc

The Linux filesystem hierarchy rewards familiarity. Once you know that configuration is always in /etc, logs are always in /var/log, and installed binaries are always in /usr/bin, you can navigate any Linux system without hesitation regardless of the distribution.

Frequently Asked Questions

What is the Linux file system hierarchy?

The Linux file system hierarchy is a standardised directory tree that starts at the root directory (/). Every file and directory on a Linux system lives somewhere under /. The layout is defined by the Filesystem Hierarchy Standard (FHS), which specifies what each top-level directory is for. Common directories include /etc for configuration, /var for variable runtime data, /home for user files, /usr for installed software, and /tmp for temporary files.

What is the difference between /bin and /usr/bin in Linux?

Historically, /bin held essential system binaries needed before /usr was mounted (in early Unix systems with separate disk partitions), while /usr/bin held user-installed programs. On most modern Linux distributions, /bin is a symbolic link to /usr/bin and there is no functional difference. The merge was completed in distributions like Fedora, Ubuntu, Debian, and Arch, and is now the standard under the FHS.

What is /etc in Linux?

/etc contains system-wide configuration files. It stands for “et cetera” historically, though it is now treated as meaning “editable text configuration.” Examples include /etc/passwd (user accounts), /etc/fstab (filesystem mount points), /etc/hosts (local hostname resolution), and /etc/ssh/sshd_config (SSH server settings). Files in /etc should be text files that administrators edit directly.

What is /var in Linux?

/var holds variable data: files whose content changes during normal system operation. This includes log files (/var/log), mail spools (/var/mail), package manager caches (/var/cache), runtime state files (/var/run, now usually a symlink to /run), and database files for installed packages (/var/lib). On servers, /var often lives on its own partition to prevent logs from filling the root filesystem.

What is /proc in Linux?

/proc is a virtual filesystem that exposes kernel and process information as files. Nothing in /proc is stored on disk. Reading /proc/cpuinfo gives CPU details, /proc/meminfo gives memory stats, and /proc// contains information about a running process. It is the primary interface for userspace tools to query kernel state.