Moving Around: Your Mental Map of the Machine
"In the terminal you are always standing somewhere. The first skill is knowing where."
Every command you run — and every command an AI suggests — executes somewhere: inside one specific folder on your machine. Half of all beginner terminal confusion is really just location confusion: the command was fine, but you were standing in the wrong place. This part builds your mental map. You'll learn to ask where you are, read a path like an address, move around freely, and create and inspect files — all without touching a mouse.
pwd → ls → cd — is the terminal equivalent of looking up from your phone to check the street signs. Run it any
time you feel lost, and always before running a command an AI wrote for you: most AI-suggested commands quietly
assume you're standing in the project folder.2.1 Where Am I?
A fresh terminal window is quiet: a prompt, a blinking cursor, and no other clues. But you're not floating in a void — the shell has already placed you inside a folder, called your working directory. Two commands turn the void into a map.
npm install in the project folder." Node is the program that runs JavaScript outside
a browser, and npm is how a Node project fetches its dependencies — the code other people wrote that it leans on rather than
rewriting. All of it lands in a node_modules folder, routinely hundreds of megabytes
of it. Which folder is your terminal actually in right now?pwd ("print working directory") answers the question in one line:
pwd
# /home/vibeThat answer — /home/vibe — is a path, the full address of the folder you're standing in (paths get
their own section next). It also names your home directory — the folder that belongs
to your account, where your files, settings and downloads live. Every account on the machine
gets one, and this one is the home of the account named vibe — you. Now look around with ls ("list"):
ls
# documents notes.txt projects pwd
"Where am I?" — prints the full path of your working directory. Instant, harmless, run it constantly.
ls
"What's here?" — lists the files and folders in the current directory (or any path you give it).
ls -l
"Tell me more" — one file per line with sizes, dates, and permissions: who's allowed to read or change each file.
The Hidden Layer: Dotfiles
Plain ls is holding out on you. Any file or folder whose name starts with a dot — a dotfile — is hidden by default. That's
where configuration lives: .bashrc, your shell's own settings file (Your Shell Config); .gitignore; and the .env file holding your API keys — an API being
a door a service opens for other programs rather than for people, which is why that file is
worth hiding (curl — Ask the Network). Add -a ("all") to see them:
ls -a
# . .. .bashrc .config documents notes.txt projects. and ... They're not files — they're built-in nicknames for "this directory" and
"the parent directory," and they show up in every folder. They're about to become very
useful in the next section.A First Peek at ls -l
The long listing packs a lot into each line. For now, read just three things: the leading d means "directory," the number before the date is the size in bytes, and the name is at the end. A byte
is one character's worth of storage, so a 118-byte file holds roughly 118 characters. The
rest of that cryptic string is the permissions code, and we decode it fully in Permissions & Config.
ls -l
# total 12
# drwxr-xr-x 3 vibe staff 4096 Jul 10 09:14 documents
# -rw-r--r-- 1 vibe staff 118 Jul 12 08:30 notes.txt
# drwxr-xr-x 4 vibe staff 4096 Jul 11 17:02 projectsThree things in that block mislead on sight. total 12 is not a count of the files
— it's how much disk they take up, measured in blocks rather than bytes. The small number just
after the permissions is a link count, not a second size. And the two names beside it, vibe staff, are the file's owner and its group. All three get taken apart in Reading ls -l.
ls -la is ls -l -a typed faster — "long listing, including hidden files," the most common ls invocation in the wild. Only single letters cluster this way, and only behind one dash (Getting Help). (On Windows, dir is the Command Prompt cousin of ls — but inside WSL, or inside Git Bash, which bundles a bash shell into Windows, ls works exactly as shown.)"What directory is my terminal in right now, and what project files are here?"
"List everything in this folder including hidden files, and explain what each dotfile is for"
2.2 Paths
Every file on your machine has an address, and that address is called a path. Learn to read paths and the whole filesystem snaps into focus — it's one big upside-down tree, and you can point at any leaf from anywhere.
~/projects/app/.env". Is that a file? A folder? Where is it? You can't
follow directions written in a language you can't read.Everything starts at the root, written as
a single slash / — the one folder every other folder lives inside. Everything else hangs somewhere
beneath it, and a path is the walk from one point to another, with / between each step. Fair warning, because the word gets reused: this root is
a place. The other root you'll meet is a person, the administrator account
in sudo, and the two have nothing to do with each other.
Reading the tree: the file .env lives at /home/vibe/projects/app/.env — root, then home, then vibe, then projects, then app.
The branches sitting beside home at the top belong to the machine rather than
to you, and a handful come up often enough to name. /bin and /usr/bin hold binaries — the programs themselves. /etc holds system-wide configuration — that's what /etc/hosts in the table below is, the short list of names your machine resolves
itself before asking the network. /tmp is scratch space anyone can write to and the machine may clear without asking. And /usr, despite the spelling, is where the system's own software lives — it
has nothing to do with users.
Absolute vs. Relative
An absolute path starts at the root with / and works from anywhere — a full street address. A relative path starts from
wherever you're currently standing — "two doors down." Both name the same file:
# Absolute: works no matter where you are
cat /home/vibe/projects/app/README.md
# Relative: works if you're standing in /home/vibe
cat projects/app/README.mdThe Four Shortcuts Every Path Uses
| Symbol | Means | Example |
|---|---|---|
/ | The root — the very top of the tree | /etc/hosts |
~ | Your home directory (here, /home/vibe) | ~/projects/app |
. | The current directory — "right here" | ./script.sh |
.. | The parent directory — one level up | ../other-project |
And they compose. Standing in ~/projects/app, the path ../../documents means "up two levels, then into documents." Now you can re-read the AI's instruction: ~/projects/app/.env is a hidden file named .env, inside app, inside projects, inside your home directory.
cd pro, TAB, watch it become cd projects/. That trailing slash is a marker meaning "this one's a folder"
— the shell mostly doesn't care either way, but the habit stops you misreading your own
commands later.cd My Projects tells the shell to cd into "My" and hands it a mystery second word. Wrap it in quotes (cd "My Projects") — or just TAB-complete, which escapes the space automatically. Better yet, name your own
folders with dashes: my-projects.Those quotes are worth understanding properly, because you'll be reaching for them for the
rest of the course. There are two kinds, and one difference that matters. Single quotes are literal — nothing inside them means anything to the shell, so '$HOME' stays five characters instead of turning into the path to your home directory, and '*.txt' stays five characters instead of becoming a list of files. Double quotes still let $NAME and $(...) expand into their values (Environment Variables) while
still protecting the spaces. Reach for single quotes when you want the shell to keep its
hands off, double quotes when you want a value in the middle of a phrase.
A backslash does the same job for exactly one character: My\ Projects is one filename,
not two words — which is what TAB completion is doing when it "escapes" a space for you. Anything
the shell would otherwise read as punctuation — a space, a *, a $, a quote mark — can be defused by putting a backslash in front of it.
"Explain this path to me piece by piece: ~/projects/app/.env"
"Give me the absolute path to my current directory and a relative path from here to my home folder"
Try It: Mind the Gap
cd "My Projects", then leave a shipped.txt behind.Loading playground...
2.3 Changing Directories
You can read the map; now walk it. cd ("change directory") moves you to any path you can name — and since you just learned to name every
path on the machine, you can now go anywhere.
~/projects/app but your terminal opens in ~. Every command the AI gives you assumes you've made the trip.cd projects/app # Walk down into a folder (relative path)
pwd # /home/vibe/projects/app — always verify
cd .. # Up one level, to projects
cd ~ # Jump home from anywhere (plain 'cd' does the same)
cd - # Bounce back to wherever you just wereThat last one is a gem most tutorials skip: cd - toggles between your two most recent locations — perfect when you're hopping between a project
and a config folder. It's also one of the rare places a lone dash is a value rather than a flag
(Getting Help) — here it stands in for "the last place I was," not for a
setting. And remember the habit from 2.2: type cd, a few letters, then TAB your way down the tree.
cd never creates, changes, or deletes anything — it only moves your point of view. Mistype a name
and the worst you get is no such file or directory, a completely harmless error. Genuinely lost? cd ~ teleports you home from anywhere. Wander boldly.Try It: Find the Lost API Key
pwd, ls -a, and cd to hunt it down. Type help for the full command list.Loading playground...
"Take me to my project folder and confirm where I ended up"
"I'm lost in some deep directory — get me back home and show me the path I took"
2.4 Making Things
So far you've been a tourist — looking, never touching. Time to build. Two commands create
the skeleton of every project you'll ever start: mkdir for folders and touch for empty files.
src folder with a components subfolder, plus a README." You could
click through a file manager… or type one line.mkdir notes # One new folder in the current directory
mkdir src tests docs # Three at once — src is short for "source"
touch README.md # One new, empty file
ls # Verify — trust, but verifyPlain mkdir has one rule: the parent must already exist. Ask it for a nested path and it refuses:
-p mkdir src/components/buttons
# mkdir: cannot create directory 'src/components/buttons': No such file or directory
mkdir -p src/components/buttons # -p = parents: create every missing one on the way
# (no output — in the shell, silence means success)mkdir -p is also re-runnable: if the folders already exist, it succeeds quietly instead of
erroring. That's why AI-generated setup scripts always reach for -p — the command is safe whether it's the first run or the fifth.touch has a funny origin story: its real job is updating a file's "last modified" timestamp — touching
it. But if the file doesn't exist, touch creates it, empty. That side effect became its main job: it's the standard
way to say "make me a blank file right here."
mkdir -p my-app/src/components my-app/tests
touch my-app/README.md my-app/src/main.js
ls -R my-app # -R walks into every folder inside, and those folders' folders tooNothing on the machine requires that shape — src, tests and docs are a convention other people will recognize, not a rule anything enforces.
And that walking-into-everything behaviour has a name, recursive, which comes back in Copying as the flag that lets
copying and deleting reach a whole tree at once.
"Set up a folder structure for a small Python project — show me the mkdir commands before running them"
"Create the standard src/tests/docs skeleton in this directory and list the result"
2.5 Looking Inside Files
An AI agent just wrote a config file into your project. Before you trust it, you want to read it — without the ceremony of opening an editor. The terminal has a whole toolkit for exactly this, graded by file size.
config.yaml?" Reading files is how you verify work — an instinct this whole
course keeps returning to.cat — dump the whole file to the screen cat config.yaml
# port: 8080
# debug: false
# database: ./data/app.dbThat file is YAML — a config format built
to be read by humans, one key: value to a line. (A config file being any file
that changes how a program behaves without changing the program itself.)
A few other extensions keep turning up and work the same way. .csv is comma-separated values: one record per line, the fields split on commas, the first line usually
naming the columns. .md is Markdown — plain text with light formatting marks, like # for a heading. .sh is a shell script. Every one of them is ordinary
text underneath: a file of characters, each character stored as a number. That's why the commands
below read all of them equally well, and why an extension is a convention for humans and editors
rather than the thing that makes a file work.
cat (short for "concatenate") is perfect for short files — it prints everything and returns your prompt.
But cat a 10,000-line log and it firehoses past you. For anything long, you want a pager:
less — read at your own pace less server.log
# Opens a full-screen reader:
# space / b page down / up
# arrow keys scroll line by line
# /error search for "error" — press Enter to run it (n = next match)
# q QUIT — back to your promptq and you're free. This matters double because man pages (First Contact) open in less too — same keys, same
escape hatch.While we're here, four escape hatches worth memorizing now — because each one has stranded somebody for an embarrassingly long time. Two are characters you type; two are chords, held down together in one motion. The comments say which is which:
q # type it — any pager: less, or a man page. One keypress, no Enter
:q! # type it — vim. Press Esc FIRST, then these three, then Enter (:wq saves instead)
Ctrl+X # chord — nano. It says so at the bottom, but nobody reads it
Ctrl+C # chord — a running command, or a line you typed but haven't run:q! is the famous one. Git — the tool that records snapshots of a project as you
work (Your Shell Config) — drops you into vim on most machines to
write the note that goes with a snapshot. The keyboard stops behaving, there's no visible way
out, and the answer is Esc then :q! then Enter, which leaves without saving. You are
not expected to learn vim today; you're just expected to be able to leave.
nano is the one worth
entering deliberately: nano notes.txt opens the file, you type the way you'd type
anywhere, and the only two chords that matter are printed at the bottom of its screen the whole
time — Ctrl+O then Enter to save ("write out"), Ctrl+X to leave. It ships on nearly every Linux machine and every Mac, and the
day A Door to Another Machine lands you on a server with a config file to fix, this is the
tool you'll reach for. (Not in the playground — its files are edited with echo and friends; nano is a real-machine comfort.)Sometimes you only care about the edges of a file — the header row of a CSV, or the most
recent lines of a log. That's head and tail:
head and tail — just the edges head server.log # First 10 lines
head -n 3 server.log # First 3 lines
tail server.log # Last 10 lines — where the newest log entries live
tail -n 20 server.log # Last 20tail -f ("follow") keeps the file open and streams new lines as they're written — the classic way to watch
a server log live while your app runs. Press Ctrl+C to stop following. cat
Short files. Whole thing, instantly.
less
Long files. Scroll, search, q to quit.
head
The beginning. Headers, first impressions.
tail
The end. Fresh log lines, latest entries.
Try It: Build Your Workspace
cd, build a project skeleton with mkdir -p and touch, then verify your work with ls and cat.Loading playground...
"Show me the last 30 lines of the newest log file in this project"
"Read the config file the agent just created and explain each setting to me"
Loading challenge...