The Terminal is a text interface to your computer. Instead of clicking icons, you type instructions. The computer reads them, executes them, and prints a response. Everything else — the history, the symbols, the conventions — follows from this one fact.
The core idea
Two layers of your Mac
The GUI you see and the shell underneath it
Your Mac has two ways to operate it. The one you know: windows, icons, a mouse. This is called the GUI (Graphical User Interface). It was introduced by Apple in 1984 specifically to make computers accessible to people who didn't want to type commands.
Underneath the GUI is an older, more direct layer: the shell. The Terminal app is a window into the shell. When you open Terminal, you're not using a different operating system — you're still on your Mac, accessing the same files, the same CPU, the same network. You're just talking to it differently.
The shell predates the GUI by about 15 years. Everything in the GUI is built on top of it. When you drag a file to the Trash, the GUI is executing the same move command you'd type in the Terminal. The GUI is a visual wrapper around instructions that have always been text.
Underneath the GUI is an older, more direct layer: the shell. The Terminal app is a window into the shell. When you open Terminal, you're not using a different operating system — you're still on your Mac, accessing the same files, the same CPU, the same network. You're just talking to it differently.
The shell predates the GUI by about 15 years. Everything in the GUI is built on top of it. When you drag a file to the Trash, the GUI is executing the same move command you'd type in the Terminal. The GUI is a visual wrapper around instructions that have always been text.
Why this matters for you
Most automation, development tools, and AI agents don't have a GUI. They were designed to run unattended — on servers, in pipelines, on a schedule. The Terminal is how you control them. Claude Code has no GUI at all. It runs entirely in the Terminal. Learning the Terminal is a prerequisite for everything in Phase 3 onward.
Key vocabulary
Terminal vs Shell vs Command Line
Three words for the same general thing — with a distinction worth knowing
These are often used interchangeably. Here's the precise meaning of each:
Terminal — the application on your Mac (the window you open). Historically, a "terminal" was a physical device: a keyboard and screen connected to a remote mainframe computer. The app is named Terminal because it plays the same role: it's the point where you interface with the machine.
Shell — the program that runs inside the Terminal, interprets your commands, and returns results. On your Mac, the default shell is called zsh (Z shell). Before zsh, the standard was bash (Bourne Again Shell). The names are historical accidents and don't tell you much, but you'll see both referenced in instructions online.
Command line — the style of interface, not a specific app. It means: you type a command, press Enter, get a response. Both Terminal and shell are part of a command-line interface.
Terminal — the application on your Mac (the window you open). Historically, a "terminal" was a physical device: a keyboard and screen connected to a remote mainframe computer. The app is named Terminal because it plays the same role: it's the point where you interface with the machine.
Shell — the program that runs inside the Terminal, interprets your commands, and returns results. On your Mac, the default shell is called zsh (Z shell). Before zsh, the standard was bash (Bourne Again Shell). The names are historical accidents and don't tell you much, but you'll see both referenced in instructions online.
Command line — the style of interface, not a specific app. It means: you type a command, press Enter, get a response. Both Terminal and shell are part of a command-line interface.
Practical rule: When people say "type this in the Terminal" or "run this in the shell" or "use the command line," they all mean the same thing: open Terminal on your Mac, type the instruction, press Enter.
What it looks like
The prompt
The line waiting for your input
When you open Terminal, you'll see something like this:
Breaking this down:
jakobmollerbeck — your username on this Mac
@Jakobs-MacBook-Pro — the machine name
~ — your current location (the tilde means "home directory" — more on this in the Symbols tab)
% — the prompt character, meaning "I'm ready for input." In older bash shells this was $ instead. Both mean the same thing: ready.
Everything after the % is where you type. The machine responds below your input. Then a new prompt appears, waiting for the next command. This loop — type, press Enter, read response, type again — is the entire interface.
What you see when Terminal opens
jakobmollerbeck@Jakobs-MacBook-Pro ~ %
jakobmollerbeck — your username on this Mac
@Jakobs-MacBook-Pro — the machine name
~ — your current location (the tilde means "home directory" — more on this in the Symbols tab)
% — the prompt character, meaning "I'm ready for input." In older bash shells this was $ instead. Both mean the same thing: ready.
Everything after the % is where you type. The machine responds below your input. Then a new prompt appears, waiting for the next command. This loop — type, press Enter, read response, type again — is the entire interface.
The Terminal looks the way it does because of decisions made in the 1960s and 70s, mostly at AT&T's Bell Labs. Understanding where these conventions came from explains why they haven't changed — and why they're used by everyone from researchers to the tools that power AI products.
Origin
Where this all comes from
A brief history that explains most of what you'll encounter
1960s · Mainframe era
Computers the size of rooms, shared by many people
Early computers were enormous and extremely expensive — one machine for an entire university or corporation. Users interacted through teletype machines: physical typewriters connected via telephone lines to the mainframe. You typed a command; the mainframe printed a response, literally on paper. There was no screen. This is where the word "terminal" comes from — it was the terminal point of the connection to the central machine.
1969–1973 · Bell Labs
Unix is invented — and with it, most of what you'll use
AT&T's Bell Labs created Unix, an operating system designed around a single philosophy: small, focused tools that do one thing well and can be combined. The pipe symbol (|), the file system structure with / as root, the concept of standard input and output — all of this was designed at Bell Labs between 1969 and 1973. Nearly everything you type in a Terminal today is a direct descendant of Unix conventions.
1970s · Teletypes replaced by screens
The physical terminal becomes a screen — but the interface stays the same
Video terminals replaced paper teletypes, but the interaction model was unchanged: type a command, get a response, repeat. This is why the interface still feels like a conversation. The conventions from the teletype era — short command names, flags with dashes, output to the screen — were kept because they already worked. The constraint of a 24-line, 80-character screen shaped many conventions that persist today, including why command names tend to be short (ls, cd, rm).
1983–1991 · GNU and open source
Unix conventions spread to the wider world
Richard Stallman's GNU project created free replacements for Unix tools, spreading the conventions into the open-source world. The bash shell (1989) became standard on most systems. Commands you'll use — ls, cd, grep, cat — were largely standardised in this period and haven't changed since.
2001 · Apple
macOS is built on Unix — Terminal is native, not an afterthought
When Apple rebuilt their operating system as macOS (then called OS X), they based it on a Unix foundation called Darwin. This is why your Mac's Terminal uses the same commands as a Linux server, and why nearly all developer instructions written for "Unix/Linux" also work on your Mac. The Terminal on your Mac is not a third-party add-on — it's an interface to the operating system's actual foundation.
Today
50-year-old conventions run trillion-dollar infrastructure
Every major cloud provider, every production server, every AI model running at scale operates on Linux — a direct Unix descendant. The commands you're learning are not a legacy curiosity. They are the universal language of computing infrastructure. The fluency you're building is exactly what your clients' CTOs use every day.
Why short names
Why commands are abbreviated
ls, cd, rm, pwd — these aren't arbitrary
The original Unix developers were typing on hardware where every character mattered — slow connections, limited screens, physical keys. They designed commands to be as short as possible:
ls = list (show files in current directory)
cd = change directory
rm = remove (delete a file)
pwd = print working directory (show where you are)
cat = concatenate (originally for joining files; now used to read them)
grep = Global Regular Expression Print (search text for a pattern)
These abbreviations were never updated because they were standardised and taught to every subsequent generation. There was no breaking-change mechanism. So you learn them as vocabulary — short words with specific meanings.
ls = list (show files in current directory)
cd = change directory
rm = remove (delete a file)
pwd = print working directory (show where you are)
cat = concatenate (originally for joining files; now used to read them)
grep = Global Regular Expression Print (search text for a pattern)
These abbreviations were never updated because they were standardised and taught to every subsequent generation. There was no breaking-change mechanism. So you learn them as vocabulary — short words with specific meanings.
Etymology worth knowing
The flag conventions also have an origin. Early Unix used single-letter flags (-l, -a) because they were typed constantly. In the 1980s and 90s, newer tools added longer, human-readable alternatives (--long, --all) for scripts and documentation. The double-dash convention for long flags was standardised by GNU. Both forms survive because old scripts still use short flags and new documentation often uses long ones. They're the same thing, two generations of convention coexisting.
Every command follows the same pattern. Understanding this pattern means you can read any command you encounter, even unfamiliar ones — and know what each part does before you run it.
The anatomy
Command structure
Every Terminal command is: verb + options + target
Every command follows this pattern:
Command — the verb. What you're asking the computer to do. Always comes first.
Flags / options — modifiers. How you want the command to behave. Preceded by - or --. Optional — most commands work without them.
Arguments — the target. What you're operating on. A file, a directory, a URL. Comes last.
Anatomy of a command
command --flag argument # Real example: ls -l ~/Desktop # ↑ verb ↑ option ↑ target # "list in detail the Desktop folder"
Flags / options — modifiers. How you want the command to behave. Preceded by - or --. Optional — most commands work without them.
Arguments — the target. What you're operating on. A file, a directory, a URL. Comes last.
More examples with the same structure
python3 summariser.py # "run this file" mkdir my-project # "make directory called my-project" cp -r old-folder new-folder # "copy recursively old-folder to new-folder" git commit -m "first version" # "git: commit with message 'first version'"
When you see an unfamiliar command: identify the three parts. The verb tells you what category of action it is. The flags tell you how. The argument tells you what it's acting on. You can usually infer what a command does from structure alone, even before looking it up.
The file system
Where things live
Your Mac's folder structure, from the Terminal's perspective
In Finder, you see icons and folders. In the Terminal, you see paths. The same structure, different representation.
The / at the very start means the root — the top of the entire file system. Every path starts here. This convention comes directly from Unix 1969. On your Mac, everything is inside /.
Your home directory (~) is /Users/jakobmollerbeck. It's where your Desktop, Documents, Downloads folders live. Most of your work will happen inside here.
The same location, two ways of seeing it
# Finder: click Macintosh HD → Users → jakobmollerbeck → Desktop # Terminal path: /Users/jakobmollerbeck/Desktop # Shorthand using tilde: ~/Desktop # These are identical. ~ is just an abbreviation.
Your home directory (~) is /Users/jakobmollerbeck. It's where your Desktop, Documents, Downloads folders live. Most of your work will happen inside here.
Mental model
Think of the Terminal as always having a "current location" — a folder you're standing in. When you type a command, it acts on that location unless you specify otherwise. Knowing where you are is the first thing to check when something isn't working. Type pwd to print your current location.
Input and output
How commands talk to each other
The Unix philosophy of connecting small tools
One of Unix's founding ideas: every command reads from an input stream and writes to an output stream. By default, input comes from your keyboard and output goes to your screen. But you can redirect both.
This is why | (pipe) works: it takes one command's output and feeds it as input to the next command. It's a literal pipe between two programs.
The > redirect sends output to a file instead of the screen:
This is why | (pipe) works: it takes one command's output and feeds it as input to the next command. It's a literal pipe between two programs.
Composing commands with pipes
ls | grep "pdf" # ls outputs a list of files # grep filters it to lines containing "pdf" # result: only pdf files shown cat notes.txt | grep "action" # read notes.txt, then filter for lines with "action"
Sending output to a file
ls > filelist.txt # Instead of printing to screen, saves to filelist.txt # If filelist.txt doesn't exist, it's created # If it does exist, it's overwritten ls >> filelist.txt # >> appends instead — adds to the end without overwriting
Why this design matters
The pipe and redirect system was Ken Thompson's invention at Bell Labs. The idea: don't build one monolithic tool that does everything. Build small tools that do one thing perfectly, and connect them. This philosophy is why you can combine ls, grep, sort, and wc into a pipeline that answers complex questions about your files — using tools built decades apart by different people. It's also the conceptual ancestor of how Claude agents chain tools together.
These are the symbols you'll encounter in commands. Each one has a specific meaning. Understanding why they work the way they do — not just what they do — means you won't need to memorise them; you'll just know them.
-
Single dash · Short flag
Options & flags
Introduces a short (single-letter) option for a command. Inherited from early Unix where typing was slow and every character was expensive. These are single letters because they were designed to be typed fast.
ls -l # long format (details) ls -a # all files (including hidden) ls -la # combine two flags together
--
Double dash · Long flag
Options & flags
Introduces a full-word option. Added by GNU in the 1980s to make scripts more readable. Functionally identical to the short version — many commands support both. The double dash is also used alone (--) to signal "end of flags; everything after this is an argument."
git --version # same as git -v ls --all # same as ls -a
/
Forward slash · Path separator
File system
Separates folders in a file path. The very first / in a path means "start from the root of the entire file system." Subsequent slashes just separate folder names. This convention dates to Unix 1969.
/Users/jakob/Desktop/report.pdf
# ↑ root → Users → jakob → Desktop → file~
Tilde · Home directory
File system
A shorthand for your home directory. Exactly equivalent to /Users/jakobmollerbeck. The shell expands it before running the command — the command never sees the ~, it sees the full path. Added to shells in the 1970s to save typing.
~/Desktop # your Desktop ~/.zshrc # hidden config file in your home dir cd ~ # go to home directory from anywhere
..
Double dot · Parent directory
File system
Move up one level in the folder hierarchy. Can be chained: ../../ goes up two levels. The convention of . for "here" and .. for "one up" was part of the original Unix file system design.
cd .. # go up one folder cd ../../ # go up two folders ls ../other # list a sibling folder
.
Single dot · Current directory
File system
Refers to where you are right now. Used when a command needs an explicit path and you mean "here." Also used to run scripts in the current directory, and as a prefix for hidden files (.env, .gitignore).
python3 ./script.py # run script in current dir cp file.txt . # copy file to current directory ls -a # shows .hidden files like .env
|
Pipe · Chain commands
Input & output
Sends the output of one command as input to the next. The Unix philosophy made concrete: combine small tools into pipelines. The name is visual — it's literally a pipe carrying data from left to right. Invented at Bell Labs, ~1973.
ls | grep "pdf" # list, then filter for pdf cat log.txt | grep "error" # find errors in log
>
Redirect · Send to file
Input & output
Instead of printing output to the screen, write it to a file. Creates the file if it doesn't exist. Overwrites if it does — no warning. Use >> to append instead.
ls > files.txt # save directory listing to file echo "hello" > note.txt # write "hello" to note.txt ls >> files.txt # append, don't overwrite
*
Wildcard · Match anything
Pattern matching
Matches any sequence of characters in a filename. The shell expands the wildcard before running the command — the command sees the actual matching filenames. Inherited from early Unix pattern-matching (called "glob" patterns).
ls *.pdf # all files ending in .pdf rm report*.txt # delete all report*.txt files ls data_* # all files starting with data_
" "
Quotes · Group with spaces
Arguments
Wraps a string that contains spaces so the shell treats it as one argument. Without quotes, the shell splits on spaces — my file.pdf is read as three separate things. Double quotes allow variable expansion; single quotes treat everything literally.
cd "Client Reports" # folder name has a space git commit -m "first draft" # message is one string
&&
And · Conditional chain
Control flow
Run the second command only if the first succeeds. If the first fails, stop. More precise than ; which runs both regardless. Useful when step 2 depends on step 1.
mkdir project && cd project # only cd into the folder if mkdir worked pip install requests && python3 script.py # only run script if install succeeded
;
Semicolon · Sequential
Control flow
Run commands one after another, regardless of success or failure. The second runs even if the first errored. Use && when order of success matters; use ; when you just want a sequence.
cd project; ls
# go to folder, then list contents (no matter what)$
Dollar sign · Variable
Variables
References a variable's value. The shell replaces $NAME with the value stored in NAME before running the command. This is how environment variables work — things like $HOME, $PATH, or your API keys stored in .env files.
echo $HOME # prints your home directory path echo $PATH # prints where the shell looks for commands echo $USER # prints your username
#
Hash · Comment
Scripts
Everything after # on a line is ignored by the shell. Used to leave notes in shell scripts. Also used at the start of a line to disable a command without deleting it.
# This line does nothing — it's a comment ls -l # this command runs; the comment is ignored
The keyboard shortcut for | on a Danish Mac keyboard: ⌥ + i. This trips people up because the pipe is used constantly in Terminal work and it's not where you'd expect it.
These are the commands you'll use in Phase 1 and 2. Not a complete reference — a focused list of what actually comes up. Learn these by using them, not by reading them.
Files and folders
Creating and moving things
Creating
mkdir project-name # make a new folder mkdir -p a/b/c # make nested folders in one step touch notes.txt # create an empty file
Copying and moving
cp file.txt copy.txt # copy file cp -r folder/ backup/ # copy folder (needs -r for recursive) mv file.txt ~/Desktop/ # move file to Desktop mv old-name.txt new.txt # rename a file
Deleting — be careful, no undo
rm file.txt # delete a file — permanent, no Trash rm -r folder/ # delete a folder and everything inside it # Never run rm -rf / — it deletes everything on the computer
There is no undo for rm. Deleted files do not go to the Trash. They are gone. Until you're confident, use mv to move things to a temporary folder instead of deleting — you can always delete later.
Reading files
Looking at file contents
Reading and searching
cat file.txt # print entire file to screen head file.txt # print first 10 lines tail file.txt # print last 10 lines tail -f log.txt # watch file update in real time (useful for logs) grep "word" file.txt # find lines containing "word" grep -r "word" folder/ # search all files in folder
Running Python
Executing scripts and managing packages
Python commands you'll use constantly
python3 script.py # run a Python file python3 --version # check Python version pip3 install requests # install a package pip3 install -r requirements.txt # install all packages from list pip3 list # see installed packages
When a script doesn't run: first check you're in the right folder (pwd and ls). Most "file not found" errors are navigation errors, not code errors.
Environment variables
How API keys work in the Terminal
The mechanism behind .env files
Environment variables are named values the shell makes available to every program it runs. API keys are stored this way so they never appear in your code.
Setting and reading environment variables
export MY_KEY="abc123" # set for this session only echo $MY_KEY # read it back # In a .env file (loaded by python-dotenv): ANTHROPIC_API_KEY=sk-ant-... # In Python: import os key = os.environ['ANTHROPIC_API_KEY']
Why this exists
Environment variables were part of Unix from the early days — a way to pass configuration to programs without hardcoding it. $PATH (which tells the shell where to look for commands) and $HOME are both environment variables set automatically when you log in. The pattern of storing API keys in .env files and loading them into environment variables is a direct descendant of this 50-year-old mechanism.
Phase 1 Terminal checklist — know these before Week 5
✓
Open Terminal and identify the prompt components
✓
Navigate to any folder using both absolute and relative paths
✓
List files, including hidden ones, with details
✓
Create a folder, create a file, move and rename them
✓
Run a Python script from the correct folder
✓
Use Tab completion without thinking about it
✓
Know what every symbol in a command does before running it