Master Linux Filesystem: Quick Guide to Understanding Directory Structure
This guide explains why mastering the Linux directory hierarchy is essential for sysadmins, outlines the FHS standard, details each top‑level directory such as /etc, /usr, /var, and provides practical commands, examples, and safety tips for navigating, troubleshooting, and managing files across common distributions.
Why understanding the Linux directory hierarchy matters
Junior engineers often know that /etc holds configuration files and /var/log stores logs, but they cannot explain the rationale behind the layout or locate unknown files. This leads to concrete problems such as:
Disk space runs low and the large files cannot be found.
Configuration for a service is unknown.
Systemd unit files for a service cannot be located.
Kernel parameters need to be changed but the correct location is unclear.
Log files that can be safely removed are not identifiable.
Understanding the design logic lets you infer answers to unknown issues instead of memorising paths.
Filesystem Hierarchy Standard (FHS) 3.0
The FHS defines the purpose of each top‑level directory. All major distributions (CentOS, Ubuntu, Debian) follow it. The hierarchy is organised along two dimensions:
Static vs. dynamic content : static files (binaries, libraries, configuration) change rarely; dynamic files (logs, caches, databases) grow over time.
System‑level vs. user‑level : system‑wide files are shared by all users; user‑level files belong to a specific user.
Typical top‑level layout (root /) is:
/
├── bin # essential commands, available in single‑user mode
├── sbin # system administration commands (usually need root)
├── boot # boot loader files
├── dev # device nodes
├── etc # system configuration files
├── home # regular user home directories
├── lib, lib64 # shared libraries
├── media # mount points for removable media
├── mnt # temporary mount points
├── opt # optional third‑party software
├── proc # kernel and process pseudo‑filesystem (read‑only)
├── root # root user home directory
├── srv # service data
├── sys # kernel and device pseudo‑filesystem (read‑only)
├── tmp # temporary files (world‑writable, sticky bit)
└── var # variable data (logs, databases, caches, queues)/bin and /sbin – essential system commands
/bin – basic user commands
Commands that must be available even when only the root partition is mounted.
# Typical files in /bin
/bin/ls # list directory contents
/bin/cp # copy files
/bin/mv # move/rename files
/bin/rm # delete files
/bin/cat # display file contents
/bin/chmod # change file permissions
/bin/chown # change file owner
/bin/date # show/set system time
/bin/echo # output text
/bin/pwd # print working directory
/bin/mkdir # create directories
/bin/grep # search text
/bin/find # locate files
/bin/tar # archive files
/bin/gzip # compress files
/bin/awk # text processing
/bin/sed # stream editor
/bin/sort # sort lines
/bin/uniq # filter duplicate lines
/bin/cut # extract fields
/bin/wc # count lines/words/bytes/sbin – system administration commands
Commands that usually require root privileges.
/sbin/ifconfig # configure network interfaces (deprecated)
/sbin/route # manage routing tables
/sbin/iptables # firewall rules
/sbin/fdisk # disk partitioning
/sbin/mkfs # create filesystems
/sbin/fsck # filesystem check
/sbin/mount # mount filesystems
/sbin/umount # unmount filesystems
/sbin/modprobe # load kernel modules
/sbin/lsmod # list loaded modules
/sbin/insmod # insert a module
/sbin/rmmod # remove a module
/sbin/sysctl # adjust kernel parameters
/sbin/halt # power off
/sbin/reboot # reboot system
/sbin/shutdown # graceful shutdown
/sbin/init # init process (PID 1)
/sbin/runlevel # show current runlevel/usr/bin and /usr/sbin
On CentOS/RHEL 7+ the directories /bin and /sbin are symlinks to /usr/bin and /usr/sbin for compatibility with older installations that kept /bin on the root partition.
# Verify on a CentOS 7 system
ls -la /bin # -> /usr/bin
ls -la /sbin # -> /usr/sbinIn minimal Docker images these symlinks may be missing, causing which ls to fail.
/usr – user programs and shared data
/usris one of the largest directories, containing most installed applications and libraries.
Key sub‑directories
/usr/bin/ # user commands (mirrors /bin)
/usr/sbin/ # admin commands (mirrors /sbin)
/usr/lib/ # shared libraries (32‑bit)
/usr/lib64/ # shared libraries (64‑bit)
/usr/lib/systemd/system/ # systemd unit files (e.g., nginx.service)
/usr/local/ # manually compiled software (higher priority than /usr)
/usr/share/ # architecture‑independent data (docs, man pages, locales)
/usr/include/ # C header files for compilation
/usr/src/ # kernel source trees (usually not used directly)Common operations
# Find which package provides a binary (nginx example)
rpm -qf /usr/sbin/nginx # CentOS/RHEL
dpkg -S /usr/sbin/nginx # Ubuntu/Debian
# Show /usr size
du -sh /usr
# List the largest items under /usr
du -sh /usr/* | sort -rh | head -20
# Example: compiling nginx with prefix=/usr/local/nginx
# Files end up in:
# /usr/local/nginx/conf/ # configuration
# /usr/local/nginx/logs/ # logs (often symlinked to /var/log/nginx)
# /usr/local/nginx/html/ # web files
# /usr/local/nginx/sbin/ # management commands/etc – system configuration
/etcstores all system‑wide configuration files. The name originates from the Unix “etcetera”.
Typical sub‑directories (selected)
/etc/passwd # user accounts (UID, GID, shell)
/etc/shadow # encrypted passwords (root‑only read)
/etc/group # group definitions
/etc/sudoers # sudo policy (edit with visudo)
/etc/hosts # static hostname resolution
/etc/hostname # system hostname (CentOS/RHEL 7+)
/etc/resolv.conf # DNS resolver configuration
/etc/sysconfig/ # CentOS/RHEL specific configs (network, firewall, SELinux)
/etc/systemd/ # systemd configuration
/etc/ssh/ # SSH daemon and client configs
/etc/nginx/ # Nginx configuration (CentOS/RHEL)
/etc/httpd/ # Apache configuration (CentOS/RHEL)
/etc/php.ini # PHP main configuration
/etc/mysql/ # MySQL configuration (my.cnf)
/etc/redis/ # Redis configuration (redis.conf)
/etc/docker/ # Docker daemon configuration (daemon.json)
/etc/kubernetes/ # Kubernetes configuration
/etc/apt/ # APT sources (Ubuntu/Debian)
/etc/yum/ # YUM configuration (CentOS/RHEL)
/etc/cron.d/ # system‑wide cron jobs
/etc/crontab # main crontab file
/etc/logrotate.d/ # log rotation configs
/etc/rsyslog.conf # syslog daemon config
/etc/firewalld/ # firewalld zones (CentOS/RHEL 7+)
/etc/iptables/ # legacy iptables rules (CentOS 6)
/etc/modprobe.d/ # kernel module load options
/etc/sysctl.conf # kernel parameters (persistent)
/etc/sysctl.d/ # fragment files (higher priority than sysctl.conf)
/etc/security/ # PAM configuration
/etc/pam.d/ # PAM module configs
/etc/login.defs # default account policies
/etc/profile.d/ # shell environment scripts
/etc/bashrc # bash configuration (interactive shells)
/etc/bash_profile # bash configuration (login shells)Practical /etc operations
# Find all nginx configuration files
find /etc -name "*nginx*" -type f
# View a network script (CentOS example)
cat /etc/sysconfig/network-scripts/ifcfg-eth0
# View hosts file
cat /etc/hosts
# View DNS resolver configuration
cat /etc/resolv.conf
# Validate SSH configuration after editing
sshd -t/var – variable data (fastest‑growing directory)
/var sub‑directories
/var/
├── log/ # system and application logs
│ ├── messages # main system log (CentOS/RHEL)
│ ├── syslog # system log (Ubuntu/Debian)
│ ├── auth.log # authentication log (Ubuntu/Debian)
│ ├── secure # security log (CentOS/RHEL)
│ ├── dmesg # kernel ring buffer
│ ├── boot.log # boot messages
│ ├── cron # cron execution logs
│ ├── nginx/ # access.log, error.log
│ ├── httpd/ # Apache logs (CentOS/RHEL)
│ ├── mysql/ # error.log, slow.log, binlog/
│ ├── redis/ # Redis logs
│ ├── docker/ # Docker logs
│ ├── kubelet/ # Kubernetes kubelet logs
│ └── audit/ # audit logs
├── lib/ # application runtime data (e.g., MySQL data, Redis dump, Docker storage)
├── cache/ # package manager caches and application caches
├── spool/ # queues (mail, cron, at)
├── tmp/ # temporary files (may survive reboot)
├── opt/ # optional software data
├── run/ # PID files and runtime sockets (e.g., nginx.pid)
├── lock/ # lock files to prevent resource conflicts
└── local/ # variable data for /usr/localLog inspection commands
# Follow system log (CentOS/RHEL)
tail -f /var/log/messages
# Follow system log (Ubuntu/Debian)
tail -f /var/log/syslog
# Follow authentication log
# CentOS/RHEL
tail -f /var/log/secure
# Ubuntu/Debian
tail -f /var/log/auth.log
# Follow nginx logs
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# Follow MySQL logs
tail -f /var/log/mysql/error.log
tail -f /var/log/mysql/slow.log
# View Docker logs (containerd format)
journalctl -u docker --since "1 hour ago"
docker logs nginx_container --tail 100 -f
# View Kubernetes logs
kubectl logs -n namespace podname --tail=100 -f
journalctl -u kubelet -n 200Disk cleanup in /var
# Show size of each subdirectory under /var
du -sh /var/* | sort -rh
# Show size of each file under /var/log
du -sh /var/log/* | sort -rh
# Find the 20 largest files anywhere under /var
find /var -type f -exec du -h {} + | sort -rh | head -20
# Find the 20 largest directories under /var
find /var -type d -exec du -h {} + | sort -rh | head -20
# Find log files older than 7 days (use with caution)
find /var/log -name "*.log.*" -mtime +7 -ls
# List current log files (exclude rotated .1, .2.gz)
ls -lhS /var/log/*.logLog cleanup risks
Do not rm /var/log/nginx/access.log; it breaks the inode and Nginx cannot write.
Correct approach: truncate -s 0 /var/log/nginx/access.log or > /var/log/nginx/access.log.
Use logrotate (e.g., logrotate -f /etc/logrotate.d/nginx) for automated rotation.
Deleting a log file that a process is still writing to will not free space until the process closes the file descriptor.
Production MySQL binlogs or relay logs must be handled according to a backup/retention policy.
/var/lib – application data
# MySQL data directory (InnoDB files)
/var/lib/mysql # default datadir
# Docker storage directory
/var/lib/docker # images, containers, volumes
docker system df -v
# Kubernetes kubelet data (often large)
/var/lib/kubelet # pod volumes, CSI driver data
du -sh /var/lib/kubelet/pods/*/dev – device files
Common device files
# Block devices
/dev/sda # first SCSI/SATA disk
/dev/sda1 # first partition on /dev/sda
/dev/vda # VirtIO disk (common in cloud VMs)
/dev/nvme0n1 # NVMe SSD
/dev/nvme0n1p1 # first partition on NVMe
# Character devices
/dev/null # discard output, EOF on read
/dev/zero # infinite zero bytes
/dev/random # blocking high‑quality random numbers
/dev/urandom # non‑blocking random numbers
/dev/loop0 # loop device for mounting ISO images
/dev/tty1 # virtual terminal (Ctrl+Alt+F1)
/dev/console # system console
# Pseudo‑terminals (SSH sessions)
/dev/pts/0
/dev/tty/dev operations for ops
# Show partition layout (more readable than fdisk)
lsblk
# Show block device attributes
blkid
# List SCSI devices
lsscsi
# List NVMe devices
nvme list
# Identify root partition
df -h
lsblk/dev/shm – shared memory
# /dev/shm is a tmpfs (default half of physical RAM)
# Used for shared memory, Redis temporary storage
df -h /dev/shm
# Example (not recommended for production):
# dir /dev/shm/redis # fast but data lost on power‑off/proc and /sys – kernel interfaces (pseudo‑filesystems)
/proc – process and system information
# System-wide information
cat /proc/cpuinfo # CPU model and core count
cat /proc/meminfo # Memory statistics
cat /proc/loadavg # Load averages
cat /proc/uptime # System uptime (seconds)
cat /proc/diskstats # Disk I/O stats
cat /proc/net/dev # Network interface statistics
cat /proc/net/tcp # TCP connections (hex)
cat /proc/net/udp # UDP connections
cat /proc/filesystems # Supported filesystems
cat /proc/mounts # Current mounts
cat /proc/cmdline # Kernel boot parameters
cat /proc/version # Kernel version
# Kernel parameters (modifiable via sysctl)
cat /proc/sys/kernel/hostname
cat /proc/sys/kernel/shmmax
cat /proc/sys/vm/swappiness
cat /proc/sys/net/core/rmem_maxCommon /proc commands
# CPU model and core count
cat /proc/cpuinfo | grep "model name" | head -1
cat /proc/cpuinfo | grep processor | wc -l
# Memory usage
cat /proc/meminfo | head -5
# System load
cat /proc/loadavg
# Inspect a specific process (PID 1234)
cat /proc/1234/maps
cat /proc/1234/cmdline | tr '\0' ' '
ls -la /proc/1234/fd/
cat /proc/1234/environ | tr '\0' '
'
cat /proc/1234/comm/sys – structured device and kernel parameters
/sys/block/ # block devices (sda, nvme0n1)
/sys/block/sda/queue/ # queue parameters (read_ahead_kb, scheduler)
/sys/class/net/ # network interfaces
/sys/class/net/eth0/operstate # up/down state
/sys/class/net/eth0/speed # link speed (requires ethtool)
/sys/devices/ # internal device tree
/sys/module/ # loaded kernel modules and parameters
/sys/power/ # power management
/sys/kernel/ # kernel parameters (e.g., transparent_hugepage)Typical /proc and /sys operations
# Temporarily adjust a kernel parameter (immediate, lost on reboot)
cat /proc/sys/net/core/rmem_max
echo 134217728 > /proc/sys/net/core/rmem_max # same as: sysctl -w net.core.rmem_max=134217728
# Make the change permanent by adding to /etc/sysctl.conf and reloading
# net.core.rmem_max = 134217728
sysctl -p
# View and change I/O scheduler for a block device
cat /sys/block/sda/queue/scheduler # e.g., cfq
echo mq-deadline > /sys/block/sda/queue/scheduler # temporary
# Permanent change via GRUB kernel parameter: elevator=mq-deadline
# View and modify swappiness
cat /proc/sys/vm/swappiness # default 60
echo 10 > /proc/sys/vm/swappiness # temporary
# Permanent: add "vm.swappiness=10" to /etc/sysctl.conf and run sysctl -p
# Check transparent hugepage settings (important for some databases)
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag/lib and /lib64 – shared libraries
# Library directories
/lib/ # 32‑bit libraries (symlink to /usr/lib)
/lib64/ # 64‑bit libraries (symlink to /usr/lib64)
# Verify symlinks
ls -la /lib # -> /usr/lib
ls -la /lib64 # -> /usr/lib64
# List shared library dependencies of a binary
ldd /usr/sbin/nginx
# Example output shows missing libraries cause "error while loading shared libraries"
# Fix by installing the required package or adjusting LD_LIBRARY_PATH
# List loaded kernel modules
lsmod
# Load a module
modprobe ip_vs_rr # IPVS load‑balancing module
# Show module details
modinfo ip_vs_rr/boot – boot files
/boot/
├── vmlinuz-5.4.0-generic # compressed kernel image
├── initrd.img-5.4.0-generic # initial ramdisk
├── System.map-5.4.0-generic # symbol table (debugging)
├── config-5.4.0-generic # kernel build config
├── grub/ # GRUB2 configuration (grub.cfg)
├── efi/ # UEFI boot files (EFI/ubuntu/...)
└── memtest86+ # memory test utilityCommon /boot operations
# List installed kernels
ls -la /boot/vmlinuz-*
ls -la /boot/initrd.img-*
# Show current kernel version
uname -r
# Clean old kernels (CentOS/RHEL)
package-cleanup --oldkernels --count=2
# or
yum remove $(rpm -qa | grep kernel | grep -v $(uname -r))
# Clean old kernels (Ubuntu)
apt autoremove --purge linux-image-$(uname -r | sed 's/-generic//')-*
apt-get autoremove -y
# Check /boot usage
df -h /bootRisk reminder
Never delete files in /boot manually; use the package manager.
Ensure the new kernel boots correctly before removing the old one.
If /boot is a separate small partition (500 MiB–1 GiB), a full /boot will prevent kernel upgrades and may render the system unbootable.
/root and /home – user directories
/root – root user home
/root/
├── .bashrc
├── .bash_profile
├── .bash_history
├── .ssh/
│ ├── authorized_keys
│ ├── id_rsa
│ └── id_rsa.pub
└── anaconda-ks.cfg # installer answer file (CentOS)/home – regular user homes
/home/admin_user/
├── .bashrc
├── .bash_profile
├── .bash_history
├── .ssh/ # authorized_keys, etc.
├── Documents/
├── Downloads/
└── .config/ # user‑level application configs # Show size of each user home
du -sh /home/*
# Show current user
whoami
id
# Change a user's home directory
usermod -d /new/home/admin_user admin_user/tmp – temporary files
/tmpis world‑writable (mode 1777) and uses the sticky bit so users can only delete their own files.
# Check usage
df -h /tmp
du -sh /tmp/*
# Find the largest files in /tmp
find /tmp -type f -exec du -h {} + | sort -rh | head -10
# Find files not accessed for 30 days
find /tmp -type f -atime +30 -ls
# Find files not modified for 30 days
find /tmp -type f -mtime +30 -lsSticky bit note : permission drwxrwxrwt (the trailing t) ensures users can only delete files they own.
/srv, /opt, /mnt and /media – auxiliary locations
/srv – service data
/srv/
├── www/ # website data (sometimes linked from /var/www)
├── ftp/ # FTP server files
├── git/ # Git repositories
└── vpn/ # VPN service data/opt – optional/third‑party software
/opt/
├── google/
│ └── chrome/
├── jetbrains/
│ └── Toolbox/
├── vmware/
└── docker-desktop//mnt and /media – mount points
/mnt/ # temporary manual mounts (e.g., ISO, extra disks)
/media/ # auto‑mounted removable media (CDs, USB drives)
# Example mounts
mount -o loop /path/to/centos.iso /mnt
mount /dev/sdc1 /mnt
mount -t nfs 10.0.0.100:/data /mnt
# Show all mounts
df -hTDisk partitions and mount relationships
Example partition‑mount output
# Show current mount points
df -h
# Sample output
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 100G 50G 50G 50% /
tmpfs 7.8G 0 7.8G 0% /dev/shm
/dev/sda2 500G 300G 200G 60% /data
/dev/sdb1 1.0T 800G 200G 80% /backup
/dev/sdc1 200G 100G 100G 50% /mnt/backup2This illustrates: /dev/sda1 is the root partition; everything under / resides here unless a subdirectory has its own mount. /dev/sda2 is mounted at /data; data under /data lives on that disk. /dev/sdb1 provides a dedicated /backup area. tmpfs is an in‑memory filesystem and does not consume disk space.
Typical partition schemes
Cloud VM (single‑disk) : only / (and optionally a separate /boot of ~1 GiB).
Physical server (multi‑disk) :
/ # root (50–100 GiB)
/boot # 1 GiB (separate)
/var # majority of space – logs, data, grows fast
swap # 1–2× RAM (or ≤ RAM if >8 GiB)
/home # separate user data partitionDatabase server :
/ # root (≈100 GiB)
/boot # 1 GiB
swap # size of RAM
/var/lib/mysql # large SSD partition for InnoDB data
/var/log/mysql # separate log partition
/backup # dedicated backup diskImpact of partitioning on operations
# Find which partition a directory resides on
df -h /var/
# Show inode information (storage location)
stat /var/log/nginx/access.log
# View partition table
fdisk -l /dev/sda
# List LVM logical volumes
lvs
pvs
vgs
# If /var/log is on its own partition, a full /var/log will not prevent the root filesystem from writing other files.
# If /var/log shares the root partition, a full disk can cause system services to fail.Summary of key concepts
The FHS design classifies directories by static/dynamic content, shareability, and system‑level/user‑level scope.
Static, system‑wide : /bin, /sbin, /usr, /etc, /lib – installed once and rarely change.
Dynamic, machine‑specific : /var, /tmp, /run – grow during operation.
Shareable : /usr, /opt – can be shared read‑only across systems.
Machine‑specific : /etc, /var, /run – contain configuration, logs, runtime state.
Essential directories to remember: /etc – all configuration files. /var/log – logs for troubleshooting. /var/lib – application data (databases, Docker storage). /proc – read‑only kernel and process information. /sys – kernel device interfaces (writable parameters). /usr/local – manually compiled software. /run – PID files, sockets, runtime state.
Practical three‑step rule for daily ops:
"Find configuration – start with /etc."
"Check logs – start with /var/log."
"Modify kernel parameters – edit /proc/sys for temporary changes or /etc/sysctl.conf for permanent ones."
By internalising the logical categories rather than memorising every path, you can infer the purpose of unknown files and navigate the filesystem confidently.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
