→ From Coder to Shipper
From Coder to Shipper · Foundations

The Terminal / Shell

The window where you talk to the operating system — one line at a time. Everything you'll ever run, deploy or debug starts here.

← / → to navigate · EN/VI switch below

Big picture

What a terminal actually is

A text window where you talk to the OS one line at a time — no buttons, no mouse.

You type, it executes

A line of text + Enter = a command. The OS does exactly what you asked, then prints the result.

The shell is the translator

The shell (bash, zsh) reads your line and tells the OS what to do. The terminal is just the window that shows it.

Commands are tiny verbs

cd, ls, grep — a handful of short words that compose into anything. AI writes the long ones for you.

No safety net

No undo, no 'are you sure?' — the OS does what you typed. Precision is the skill.

The prompt

Who am I @ where am I?

Every command starts with the prompt: who you are, which machine, and the folder you're standing in.

ops@vps — zsh
student@laptop:~/projects$ ls
app docs notes.md
student@laptop:~/projects$ cd ~/notes
student@laptop:~/notes$ pwd
/home/student/notes
← the prompt updated after the cd — it's your GPS
01
Part 1

Files & folders are a tree

Everything on a server is a file, organized in folders that nest like tree branches. You're always standing in one of them.

Part 1 · the tree

Every location is a path

A path is just an address. '/' is the root of the tree; a path is a walk down it.

the-file-tree
/home/student            ← your home folder
├── projects
│   └── app
│       ├── index.py
│       └── config.yml
├── notes
│   └── ideas.md
└── .ssh                 ← dotfolder (hidden)

/home/student/projects/app   ← absolute: full address from /
projects/app                 ← relative: from where you stand

Absolute paths start at the root; relative paths start where you stand.

Part 1 · paths

Absolute vs relative

Two ways to point at the same file. Absolute never lies; relative is shorter but depends on where you stand.

Absolute — the full address

Starts at /: /home/student/notes/ideas.md. Works no matter where you're standing.

Relative — from where you stand

notes/ideas.md means 'the notes folder next to where I'm standing right now'.

~ = your home

The tilde is shorthand for /home/<you>. ~/notes saves you typing the full address.

When to use which

Relative for quick local work; absolute when it must work from anywhere (configs, scripts).

Part 1 · navigating

pwd, cd, ls — the first three commands

The names are shortened English words — that's the trick to remembering them: pwd = print working directory, cd = change directory, ls = list.

ops@vps — zsh
$ pwd ← print working directory — where am I?
/home/student
$ cd projects ← change directory — walk into a folder
$ ls ← list — what's in here?
app docs
$ ls -la ← -a shows hidden files, -l = full detail
drwxr-xr-x 2 student student 4096 app
-rw-r--r-- 1 student student 220 notes.md
$ cd .. ← up one level (.. = the parent folder)
$ cd ~ ← ~ = home, works from anywhere
Part 1 · feel it

A walk down and back up

pwd after every step — watch the address change. That's the whole skill: always know where you are.

ops@vps — zsh
$ pwd
/home/student
$ cd projects
$ cd app
$ pwd
/home/student/projects/app
$ cd .. ← one step back (.. = parent)
$ pwd
/home/student/projects
$ cd .. ← and back to home territory
$ pwd
/home/student
Part 1 · the mental model

The current directory — 'you are here'

The shell keeps one pointer: the folder you're standing in. Most commands act on it by default.

cd moves the pointer

. = stay, .. = up one level, ~ = home, / = the root. That's all the movement you need.

Bare names use it

Type notes.md and the shell looks in your current folder — no full address needed.

It feels like walking

You're not 'running a program on a server' — you're a person walking through folders, opening doors as you go.

pwd = check the map

Lost? pwd tells you exactly where you are. It's the most retyped command in existence.

02
Part 2

Creating & managing files

Five verbs cover nearly all file work — and again, the names are the clue: make, touch, copy, move, remove.

Part 2 · the five verbs

mkdir, touch, cp, mv, rm

A complete file-management session — that's the whole toolkit.

ops@vps — zsh
$ mkdir site ← make directory — a new folder
$ touch site/index.html ← touch = stamp the file; creates it (empty)
$ cp site/index.html site/backup.html ← copy — clone the file
$ mv site/backup.html site/old.html ← move — relocate; also renames
$ ls site
index.html old.html
$ rm site/old.html ← remove — delete. No undo!
$ ls site
index.html
Part 2 · don't mix them up

cp clones, mv relocates

The classic mix-up: after mv the original is gone. After cp it's still there.

cp — the copy

cp a b → both a and b exist. The original survives; b is an independent clone (edit one, the other is untouched).

mv — the move

mv a b → only b exists. The original is gone. mv is also your rename command: mv old.html new.html.

Part 2 · folders too

Working with whole folders

Same verbs, folder superpowers: -p builds nested paths, -r copies whole folders, and mv can drop a file into a folder.

ops@vps — zsh
$ mkdir -p site/static/css ← -p: create every level at once
$ cp -r site site-backup ← -r: copy the whole folder, recursively
$ ls
site site-backup
$ mv site-backup archive/ ← ending in / = drop it INTO that folder
$ ls archive
site-backup
Part 2 · the one that hurts

Why rm is scary

There is no trash bin on a server. The command you type is the last word.

No trash, no undo

rm deletes data immediately and for good. There is no 'restore' button.

rm -r = the whole folder

With -r it eats folders and everything inside, recursively. One typo far from home is expensive.

Think before you type

Pause, read the command out loud, check the path. Your fingers are faster than your judgment.

rm -i — the safety net

The -i flag makes rm ask 'really?' before each delete. A great habit while you're learning.

03
Part 3

Reading content & logs

The terminal's daily job: peek inside files and watch programs write their logs.

Part 3 · the reader's toolkit

Six verbs for reading

The names are the mnemonic: head and tail are the two ends of a file. cat for small, tail for fresh, grep to find.

CommandWhy it's named that — and what it gives you
cat file'concatenate' — it prints the whole file, top to bottom. For short files.
head file'the head' — the first 10 lines. What does the file start with?
tail file'the tail' — the last 10 lines, where the newest stuff lives.
tail -f fileLive mode: new lines print as they appear. This is how you watch logs.
grep err fileSearch — keeps only lines containing 'err'. From 'get regular expression'.
less file'less' — page through a big file with the arrows; q quits.
Part 3 · watching live

tail -f: watch a log breathe

Your shipper superpower: open tail -f on a log and every new line appears the moment it's written. Ctrl-C to stop.

ops@vps — zsh
$ tail -f /var/log/nginx/access.log
10.0.0.5 - - "GET / HTTP/1.1" 200
10.0.0.5 - - "GET /style.css" 200
← lines appear as they happen — no refresh needed
10.0.0.5 - - "POST /login" 500
^C ← Ctrl-C stops the watch
Part 3 · hunting errors

tail -20 and grep: find the bad lines

When something breaks, you don't read 10,000 lines — you take the last 20, then grep the ones that hurt.

ops@vps — zsh
$ tail -20 /var/log/nginx/access.log ← last 20 lines only
10.0.0.5 - - "GET /" 200
10.0.0.7 - - "GET /api/users" 200
10.0.0.5 - - "POST /login" 500
10.0.0.7 - - "GET /static/app.js" 200
$ grep 500 /var/log/nginx/access.log ← keep only the broken ones
10.0.0.5 - - "POST /login" 500
← from thousands of lines to the one that matters
Part 3 · put it together

The shipper's 4-step debug loop

Almost every 'it's broken' in this course gets solved with this exact loop.

  1. 1

    Watch

    tail -f on the log before you change anything. See what the app is actually doing.

  2. 2

    Reproduce

    Trigger the error (click the button, send the request) and watch the log line appear live.

  3. 3

    Hunt

    Ctrl-C, then grep the log for the error: grep 500 access.log. Isolate the bad lines.

  4. 4

    Fix & verify

    Change the code (AI helps), restart, tail -f again — the 500 is gone, 200s roll in.

04
Part 4

Pipes & redirects

The mental model only: how a command's output flows into the next command — or into a file.

Part 4 · the mental model

Four symbols, one idea: flow

One idea: every command prints text, and these four symbols steer that text somewhere useful. Watch it happen on the next slides.

| — the pipe

cmd1 | cmd2 — cmd1's output becomes cmd2's input. The daily pattern: cat file | grep word.

> — write to a file

ls > out.txt — capture the output in a file (overwrites whatever was there).

>> — append

ls >> out.txt — add to the end without erasing. This is how logs grow.

2> — the errors

Commands print errors on a separate channel. 2> err.log captures just the errors.

Part 4 · watching it flow

The pipe in action

Every command prints text; | hands that text to the next command. The classic pattern: cat file | grep word.

ops@vps — zsh
$ ls
app.py main.py notes.txt
$ ls | grep .py ← ls prints the list; grep keeps only lines with '.py'
app.py main.py
$ cat config.yml | grep port ← THE pattern: print the file, keep the matches
port: 8000
← same pattern, any source: swap cat for ls, or any command that prints
Part 4 · why pipes exist

Two steps or one line?

Before pipes, chaining meant juggling temp files. The pipe deletes the middle step.

ops@vps — zsh
$ cat access.log > big.txt ← the long way: dump to a temp file
$ grep 500 big.txt > errors.txt
$ rm big.txt ← and clean up
$ cat access.log | grep 500 > errors.txt ← one line, no temp file
← the pipe passes the text in memory — nothing touches disk
Part 4 · chain as deep as you like

Chains: small tools, big answers

Each pipe hands text to the next command. Three tools in a row, and you've written a query — no programming needed.

ops@vps — zsh
$ ls
app.py main.py notes.txt README.md
$ ls | grep .py ← step 1: only the python files
app.py main.py
$ ls | grep .py | wc -l ← step 2: and how many is that?
2
← wc -l counts lines — each file was exactly one line
Part 4 · sending it somewhere

> and >>: output becomes a file

Arrows point where the text goes: > writes (and overwrites), >> appends, and 2> catches the error channel.

ops@vps — zsh
$ ls > files.txt ← write the list into a file (overwrites)
$ cat files.txt ← prove it landed
app.py main.py notes.txt
$ echo "retry 1" >> log.txt ← >> appends; it does not erase
$ echo "retry 2" >> log.txt
$ cat log.txt
retry 1
retry 2
$ ls /nope 2> err.txt ← the error text goes to its own file
$ cat err.txt
ls: cannot access '/nope': No such file or directory
05
Part 5

The big picture

How the machine works under your fingers — and where this window takes you in the rest of the course.

Part 5 · the machine

What actually happens when you hit Enter

A 30-second tour of the machinery behind every command.

Your command is a program

ls, git, docker — each is a tiny executable file somewhere on disk. You're just asking the OS to run it.

PATH finds it for you

A list of folders the shell searches. That's why you can type git instead of /usr/bin/git — from anywhere.

Two output channels

stdout = results, stderr = errors. That's exactly why 2> exists — you can grab the errors alone.

0 = success

Every command ends with an exit code: 0 = all good, anything else = it failed. You (and scripts) check it.

Big picture

The terminal is the OS's remote control

There is no second door into the machine. Every 'tool' you'll ever use is just a command you run in this window.

git, docker, nginx…

…are all just commands in your terminal. Same window, same prompt, same one-line-at-a-time rhythm.

The course builds on this

Every future day — containers, web servers, HTTPS — is you typing a few lines here and reading the result.

AI writes, you run & read

You'll paste commands AI gives you. The skill is knowing what each line is for — and spotting when the output lies.

Output is truth

The terminal never hides its work: it prints what happened. Learn to read it and nothing surprises you.

Big picture · your course map

The commands that carry this course

You'll meet these on the coming days — every one of them is just a command in this same window.

CommandJob in this course
docker compose up -dBring up the whole stack (app, database…) as containers.
nginx -tCheck the config is valid before you reload it.
git pullFetch the latest code from your repo.
curl http://localhost/Ask your own server for a page — the fastest 'is it alive?' test.
systemctl status nginxIs the service running? Since when? What is it doing?

pwd. cd. ls. That's the door.

Open a terminal, type pwd, and go walking. Every tool in this course lives inside that window.