Phase 1 · FOUNDATIONS
The Linux filesystem: where everything lives
By the end of today
- Map the Linux filesystem tree and name what each top dir holds
- Tell an absolute path from a relative one, and / from ~
- Know where config and logs live: /etc versus /var
The Linux filesystem: one tree, rooted at /
On Windows you have C:\ and D:\ — separate drives with separate letters. Linux has no drive letters. Everything lives in one single tree, and the top of that tree is /, called root. Plug in a USB stick or mount a network share and it does not become “E:” — it gets mounted into a folder somewhere under /. One tree, always.
That tree is not random. Almost every Linux distribution follows the Filesystem Hierarchy Standard (FHS), which fixes what goes where. Learn it once and you can walk an Ubuntu server, a Red Hat box, or a Docker container blindfolded. Here are the directories you will touch constantly:
/etc— system-wide configuration. Plain text files that tell programs how to behave:/etc/ssh/sshd_config,/etc/hosts,/etc/os-release. You edit/etcdeliberately; nothing should be writing here on its own./var— data that varies as the machine runs. The big one is/var/log(every log you will ever grep), plus caches, spools and databases. When a disk fills up at 3 a.m.,/varis your first suspect./home— one folder per human user (/home/pushkar): your files, your configs, your playground. The root user is the exception — its home is/root./usr— installed software: programs, libraries, and their read-only data. Most commands you run live in/usr/bin./bin,/sbin— core commands. On modern Ubuntu these are just symlinks into/usr/binand/usr/sbin(the “usr-merge”), so do not be surprised when/binand/usr/binlook identical./tmp— scratch space anyone can write to, wiped on reboot. Never keep anything you care about here./proc— not real files at all. The kernel invents these on the fly to expose live process and system info;cat /proc/cpuinforeads straight from the running kernel.
Two more ideas make the tree usable. First, absolute vs relative paths. An absolute path starts from / and means the same thing anywhere: /var/log/syslog. A relative path is read from wherever you are standing right now — log/syslog means “the log folder inside my current directory.” pwd (“print working directory”) tells you where “here” is. Scripts should prefer absolute paths, because a cron job or CI runner starts in a different place than your terminal.
Second, / versus ~. / is the very top of the whole system. ~ is a shortcut for your home directory — /home/pushkar for you, /root for the root user. cd / climbs to the top; cd ~ (or just cd) drops you home. The difference is life-or-death: rm -rf aimed at / destroys the machine; aimed at ~ it only wrecks your own files.
Real world: Picture a large government office where every kind of paper has exactly one room: rule-books and policies in the records room, the day’s incoming applications in the mail room, each clerk’s own drawer for personal files, shared stationery in the store room. Nobody wonders where a document goes — the building’s layout decides it. The Linux filesystem is that building:
/etcis the rule-book room,/varis the mail room where fresh paperwork piles up,/homeholds each user’s desk, and the FHS is the rule that every office follows the same floor plan.
A named example makes it concrete. When you apt install nginx, nginx’s Debian package drops its config into /etc/nginx/ and writes access logs to /var/log/nginx/ — on Ubuntu, Debian, or any FHS-compliant distro. That is why a runbook that says “check /var/log/nginx/error.log” works on a server you have never touched: the standard, not the machine, decides where things land.
Knowing the tree is the difference between poking around and hoping, and walking onto any server to head straight for the file you need.
Hands-On Lab
Budget about 20 minutes. Open your WSL2 Ubuntu 24.04 terminal (if you have not set up WSL2 yet, do Day 0 first — macOS and Linux users can follow along in their built-in terminal). Type each command yourself and read every line of output; today the goal is to walk the tree, not to memorise it.
# 1. What hangs off the root of the tree? Every top-level FHS directory.
ls /
# Output (a WSL2 noble box; a plain cloud VM omits the *.usr-is-merged markers and init):
# bin bin.usr-is-merged boot dev etc home init lib lib.usr-is-merged lib64 lost+found media mnt opt proc root run sbin sbin.usr-is-merged snap srv sys tmp usr var
# 2. Same listing, but -F marks each entry's type: @ = symlink, / = directory, * = executable.
# bin, lib, sbin and lib64 are @ symlinks (the usr-merge), init* is the WSL2 launcher, and the *.usr-is-merged dirs are usr-merge markers.
ls -F /
# Output:
# bin@ bin.usr-is-merged/ boot/ dev/ etc/ home/ init* lib@ lib.usr-is-merged/ lib64@ lost+found/ media/ mnt/ opt/ proc/ root/ run/ sbin@ sbin.usr-is-merged/ snap/ srv/ sys/ tmp/ usr/ var/
# 3. Walk into the "config room" and skim what real configuration looks like.
cd /etc && ls
# Output (trimmed — /etc holds ~150 entries):
# adduser.conf apt bash.bashrc cron.d fstab group hostname hosts
# os-release passwd profile ssh sudoers systemd ...
# 4. Read the file that names the distro and version — note the hyphen, not an underscore.
cat /etc/os-release
# Output (trimmed; your point release — 24.04.1, .2, .3 … — will differ):
# PRETTY_NAME="Ubuntu 24.04.2 LTS"
# NAME="Ubuntu"
# VERSION_ID="24.04"
# VERSION_CODENAME=noble
# ID=ubuntu
# 5. Where do logs live? /var/log — your first stop on almost any incident.
ls /var/log
# Output (trimmed — a stock box holds ~40 entries: auth.log, kern.log, syslog.1, …):
# alternatives.log apt btmp dpkg.log journal lastlog syslog wtmp
# 6. Watch the tail of a real log. dpkg.log records every package change and is world-readable.
tail -n 3 /var/log/dpkg.log
# Output (your dates, versions and packages will differ):
# 2026-07-08 10:32:01 status installed libc6:amd64 2.39-0ubuntu8.3
# 2026-07-08 10:32:02 status installed base-files:amd64 13ubuntu10.2
# 2026-07-08 10:32:02 status installed bash:amd64 5.2.21-2ubuntu4
# 7. List your home INCLUDING the hidden dotfiles: -a shows them, -l goes long.
ls -la ~
# Output (dates and sizes will differ):
# total 20
# drwxr-xr-x 2 pushkar pushkar 4096 Jul 8 10:41 .
# drwxr-xr-x 3 root root 4096 Jul 8 10:35 ..
# -rw------- 1 pushkar pushkar 35 Jul 8 10:41 .bash_history
# -rw-r--r-- 1 pushkar pushkar 220 Jul 8 10:35 .bash_logout
# -rw-r--r-- 1 pushkar pushkar 3792 Jul 8 10:35 .bashrc
# -rw-r--r-- 1 pushkar pushkar 828 Jul 8 10:35 .profile
# 8. After all that, where is "here"? We ran cd /etc back in step 3 and never left.
pwd
# Output:
# /etc
# 9. A bare cd (no argument) drops you straight back to your home — the ~ shortcut.
cd
pwd
# Output:
# /home/pushkar
# 10. Prove /proc is not on disk: the kernel invents these files live, on read.
cat /proc/cpuinfo | head
# Output (your CPU will differ — this is generated fresh by the running kernel):
# processor : 0
# vendor_id : GenuineIntel
# cpu family : 6
# model : 140
# model name : Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
# stepping : 1
# microcode : 0xffffffff
# cpu MHz : 2803.200
# cache size : 12288 KB
# physical id : 0
Before you close the terminal, trace the path you just walked out loud: from / at the top, into /etc for config, over to /var/log for logs, home to ~ for your own files, and into /proc for the kernel’s live view — that mental map is what lets you land on any server and head straight for the file you need.
Common Errors & Fixes
These three trip up almost everyone in their first week on the tree. Read the error text slowly — learning to parse it is the actual skill.
Common error: Curiosity about a locked system file — running
cat /etc/shadowas a normal user — prints:cat: /etc/shadow: Permission deniedWhy:
/etc/shadowstores password hashes, so it is deliberately readable only by root (-rw-r-----, ownerroot, groupshadow). A normal user likepushkaris not in that group and is refused. Linux enforces this per file — no exception for the curious.Fix: You rarely need to read it at all; if you genuinely do, borrow root’s rights for one command with
sudo cat /etc/shadow. Whatsudodoes — and why you should not prefix everything with it — is Day 5.How you’d spot it in prod:
Permission deniedin a service or CI log almost always means the process runs as a user without rights on that path. Check who owns the file and who the process runs as before reaching forsudo— the fix is usually ownership, not privilege.
Common error: Reaching for the distro file but typing an underscore —
cat /etc/os_release— prints:cat: /etc/os_release: No such file or directoryWhy: The real file is
os-release, with a hyphen. The shell is completely literal: it looked for a file spelled exactlyos_release, found none, and said so. It does not guess the nearest match.Fix: Retype with the hyphen:
cat /etc/os-release. Better habit — type/etc/osthen pressTaband let completion fill in the real name, so the typo is caught before you hit Enter.How you’d spot it in prod:
No such file or directoryon a path you “know” exists is nearly always a typo, the wrong directory, or a relative path resolved from somewhere unexpected. Confirm withlson the parent directory and checkpwdbefore assuming the file is actually gone.
Common error: Coming from Windows and treating paths as case-insensitive —
cd /Etc— prints:bash: cd: /Etc: No such file or directoryWhy: Linux filesystems are case-sensitive:
/Etc,/etcand/ETCare three different names, and only/etcexists. Windows (C:\) treats them as the same thing, which is why this catches almost every newcomer arriving through WSL.Fix: Use the exact lowercase name:
cd /etc. Tab-completion helps here too — it only completes the casing that actually exists on disk.How you’d spot it in prod: Case bugs love to hide until deployment — a file referenced as
Config.yamlin code but saved asconfig.yamlworks on a Windows or macOS laptop, then fails on the Linux server or in CI. Match case exactly everywhere, including in scripts and Dockerfiles.
The Linux Filesystem Interview Questions
Cover the answers below and say your own version out loud first — name what /etc, /var and ~ are before you reveal each answer. Recalling before revealing is what makes these stick when an interviewer asks them cold. The four questions and answers render right after this note.
Go Deeper
Optional extras if you have ~30 more minutes today:
- 5 min — Run
man hierin your terminal. It is the built-in manual page describing the whole filesystem hierarchy, straight from your own machine. - 10 min — Skim the Filesystem Hierarchy Standard (Linux Foundation) — you do not need to memorise it, just see that the tree really is a written spec.
- 15 min — Read the “Introduction to Linux” section of the Linux for DevOps guide for how these directories fit the wider server-side picture.
What is the difference between /etc and /var? Both
/etc holds system-wide configuration — plain text files that tell programs how to behave, like /etc/ssh/sshd_config or /etc/os-release. It is meant to be static and edited deliberately; nothing should write to it during normal running. /var is the opposite: data that varies while the system runs — logs in /var/log, caches, spool queues, databases. The rule I use is simple: config you set lives in /etc, state the machine generates lives in /var. That matters for backups and containers — you treat the two very differently, and you rarely bake /var into an image because it fills up at runtime.
What is the difference between an absolute and a relative path? Both
An absolute path starts from the root of the filesystem — it begins with a slash, like /var/log/syslog, and means the same thing no matter where you are standing. A relative path is resolved from your current directory: log/syslog means 'the log folder inside wherever I am right now.' You check where 'here' is with pwd. In DevOps this bites people constantly — a script using relative paths works when you run it by hand from your home directory, then fails in a cron job or CI runner that starts somewhere else. The safe habit is absolute paths in scripts, relative paths only for quick interactive work.
Where do logs live on a Linux server, and how do you find them? Service
On most Linux servers logs live under /var/log. System and boot messages sit in /var/log/syslog; authentication and sudo attempts in /var/log/auth.log; individual services often get their own file or folder, like /var/log/nginx/. My first move on an unfamiliar box is ls /var/log to see what is there, then tail -f a file to watch it live. On modern Ubuntu, systemd services also log to the journal, which you read with journalctl rather than a flat file — that is Day 10. Knowing logs live in /var also explains a classic outage: /var fills up, logs can no longer be written, and services start failing for no obvious reason.
What is the difference between / and ~? Both
/ is the root of the entire filesystem — the single top of the tree that everything else hangs off. ~ is a shortcut for your home directory, which for me is /home/pushkar; for the root user it is /root. So cd / takes you to the very top, while cd ~ (or just cd with no argument) takes you home. People mix these up early and it is a meaningful slip: a destructive command like rm -rf aimed at / is a catastrophe, aimed at ~ it merely wrecks your own files. Interviewers like this one because it quietly checks whether you understand the difference between the whole system and your little corner of it.
Quick check
Mark Day 2 complete
You know the map now — tomorrow you learn to move through it, copying, renaming and deleting files without a safety net.
Stuck on today’s lab? Ask in Mission 90 Q&A