📁

Level 3 of 24

Filesystem

The Linux directory hierarchy, links, inodes, and everyday file operations.

Every Linux administration task eventually comes down to files: configuration files, log files, device files, even processes and hardware are represented as files under Linux's "everything is a file" philosophy. This level builds fluency navigating and manipulating the filesystem before you touch anything more advanced.

Prerequisites

  • • Level 2: Command Line

By the end of this level, you can

  • ✓ Explain what the major top-level directories are actually for
  • ✓ Distinguish absolute and relative paths without hesitating
  • ✓ Use find, cp, mv, and rm confidently and safely
  • ✓ Explain the difference between a hard link, a symbolic link, and an inode

The Linux Filesystem Hierarchy Standard (FHS)

What /etc, /var, /usr, and the rest actually store, and why the layout is standardized. · 9 min

Linux organizes everything under a single root directory, `/` — there are no separate drive letters like `C:\`; even a second disk gets mounted as a subdirectory somewhere under `/`. The Filesystem Hierarchy Standard (FHS) defines what each top-level directory is conventionally used for, and while distributions vary slightly, the core layout is consistent enough that "where does X live" has a predictable answer almost everywhere.

`/etc` holds system-wide configuration files (almost everything you'll edit as an administrator lives here). `/var` holds variable data that changes as the system runs — logs (`/var/log`), spool files, caches. `/home` holds personal directories for each user. `/usr` holds the bulk of installed software and its supporting files — despite the name, it does not mean "user". `/bin`, `/sbin`, `/usr/bin`, `/usr/sbin` hold executables (the sbin variants are conventionally for system administration commands). `/tmp` holds temporary files that may be cleared on reboot. `/proc` and `/sys` are virtual filesystems — they don't store data on disk at all, but expose live kernel and process information as if it were files, which is how tools like `ps` and `free` get their data.

`/root` is the root user's home directory (distinct from the root of the filesystem, `/` — a common early point of confusion). `/opt` conventionally holds optional third-party software not managed by the distribution's package manager. `/mnt` and `/media` are conventional mount points for manually mounted and removable media respectively. Knowing this map means that on a completely unfamiliar server, you already know roughly where to look for a given category of file before you've read a single piece of that system's specific documentation.

CommandPurposeExample
treeDisplay a directory structure as a visual tree (may need installing)tree -L 2 /etc
df -hShow disk space usage per mounted filesystem, human-readable—
  • • /etc — system-wide configuration
  • • /var — logs, caches, and other data that changes at runtime
  • • /home — personal user directories
  • • /usr — the bulk of installed software
  • • /tmp — temporary files
  • • /proc, /sys — virtual, kernel/process information, not real files on disk

Takeaway: The FHS layout is consistent enough across distributions that "which directory holds X" is almost always answerable from this map alone, before you've read that system's specific documentation.

Absolute paths, relative paths, and hidden files

Why `cd docs` and `cd /docs` can mean completely different things. · 7 min

An absolute path always starts with `/` and describes a location from the filesystem root, unambiguous no matter where you currently are — `/var/log/nginx/error.log` means the same thing regardless of your current directory. A relative path describes a location relative to your current directory and has no leading `/` — `logs/error.log` only resolves correctly if you're already standing in the right parent directory. Scripts that hard-code relative paths are a classic source of "works on my machine" bugs, because the script's behavior silently depends on which directory it happens to be run from.

Two special relative references appear constantly: `.` refers to the current directory, and `..` refers to the parent directory — `cd ../..` moves up two levels. `~` is shorthand for your home directory (`cd ~` or just `cd` with no argument both take you home), and `cd -` returns you to whichever directory you were in before your last `cd`, which is a genuinely useful habit once it becomes muscle memory.

A file or directory whose name starts with a dot (`.bashrc`, `.ssh`) is conventionally "hidden" — `ls` won't show it by default, but `ls -a` will. This isn't a real permission or security feature, just a display convention to keep configuration/dotfiles out of a normal directory listing — anyone can still read a dotfile's contents with normal read permissions.

CommandPurposeExample
ls -aList all entries including hidden (dot) files—
realpathResolve and print the absolute path of a given relative pathrealpath ./config.txt

Common Mistakes

  • ⚠ Writing scripts that assume a specific working directory instead of using absolute paths or `cd`-ing explicitly first
  • ⚠ Assuming a dotfile is "hidden" from other users on the system — it's only hidden from a default `ls`, not from anyone with read permission

Takeaway: When in doubt, use absolute paths in scripts and automation — relative paths are convenient interactively but a common source of bugs the moment a script runs from an unexpected directory.

Essential file and directory operations

touch, mkdir, cp, mv, rm, and find — and the flags that separate careful use from data loss. · 10 min

These commands do the bulk of everyday file manipulation. `touch` creates an empty file (or updates an existing file's timestamp without changing its content). `mkdir` creates a directory — `mkdir -p a/b/c` creates the full nested path in one call, creating any missing parent directories along the way, and won't error if `a/b` already partially exists. `cp` copies files (`cp -r` for directories, recursively). `mv` moves or renames — Linux has no separate "rename" command; moving a file to a new name in the same directory is how renaming works.

`rm` deletes, and it deserves real caution: there is no recycle bin. `rm -rf` (recursive, force) will silently and permanently delete an entire directory tree with no confirmation, and a single misplaced space (`rm -rf $VAR /` instead of `rm -rf $VAR/` when `$VAR` is unset or empty) has destroyed production systems more than once. Always double-check the exact path — especially in a script — before running `rm -rf`, and consider `rm -i` for interactive confirmation on anything you're unsure about.

`find` searches a directory tree by name, type, size, modification time, and more — genuinely more powerful than `ls` for anything beyond "what's in this one directory". `find /var/log -name "*.log" -mtime +30` finds log files older than 30 days, a pattern you'll reuse constantly for cleanup scripts. `locate` searches a prebuilt index instead of walking the live filesystem, so it's faster but can be stale if the index (`updatedb`) hasn't run recently.

CommandPurposeExample
touchCreate an empty file or update a timestamptouch newfile.txt
mkdir -pCreate a directory, including missing parentsmkdir -p project/src/utils
cp -rCopy a file or directory (recursive for directories)cp -r src/ backup/
mvMove or rename a file/directorymv old-name.txt new-name.txt
rm -iDelete, prompting for confirmation on each filerm -i *.tmp
findSearch a directory tree by name, type, age, size, etc.find /var/log -name "*.log" -mtime +30

Common Mistakes

  • ⚠ Running `rm -rf` with an unquoted variable that could be empty, turning `$DIR/*` into `/*` if $DIR is unset
  • ⚠ Forgetting `-r` on `cp` or `mkdir -p` for nested paths and getting a confusing error instead of the expected result
  • ⚠ Using `locate` and trusting a result that's actually stale because the index hasn't updated since a recent change
🧪

Hands-On Lab

Build and clean up a project directory structure

Objectives

  • ✓ Create a nested project directory structure in one command
  • ✓ Populate it with placeholder files
  • ✓ Find files matching a specific pattern
  • ✓ Safely remove only what's intended

Instructions

  1. Create the structure `project/src`, `project/logs`, and `project/backup` in a single `mkdir -p` command.
  2. Create three empty files under `project/logs`: `app.log`, `error.log`, and `debug.log` using `touch`.
  3. Use `find project/logs -name "*.log"` to confirm all three are found.
  4. Copy `project/logs` to `project/backup/logs-backup` using `cp -r`.
  5. Remove only `debug.log` from the original logs directory, leaving the backup and the other two files untouched.
Hints (2)
  • Remember `mkdir -p` can create multiple sibling directories in one call using brace expansion: `mkdir -p project/{src,logs,backup}`.
  • Double-check the exact path before running any `rm` command — verify with `ls` first if you're unsure.

Takeaway: Treat `rm -rf` with the same caution you'd treat a loaded tool — verify the exact path first, every time, especially inside a script where a variable could silently be empty.

Sponsor / Advertisement