Groundwork

Foundations

The command line & Unix: the bedrock under everything else.

Once you can open a terminal and move around, this is the next layer: the core commands, how to chain them, how to write a small script, and — the part most guides skip — what "Unix" actually is and how macOS, Linux, and WSL fit together. None of the other tools, or the agents using them, make full sense without it.

When you'll want this Something broke and you realized you cannot navigate, inspect files, or run commands without the agent.
Come here after Getting started

This page assumes you've done Getting started — you can open Ghostty, read the prompt, and use cd/ls. Here we widen the toolkit and explain the ground it all stands on.

Quick reference — core commands
cp / mv / rm copy / move / remove
mkdir / touch make folder / file
cat / less show / page a file
grep find text in files
find find files
| pipe output → next command
> / >> write / append to a file
chmod +x make a script runnable
man / --help read the manual
CtrlC stop a command

#A bigger toolkit

Beyond moving around, these are the verbs you'll use constantly. (This setup swaps a few for nicer versions — ls→eza, cat→bat, and grep/find have faster cousins rg/fd on the Shell page — but the classics below are everywhere, so they're worth knowing by name.)

cp src dstCopy a file (cp -r for a folder)
mv src dstMove or rename
rm fileRemove a file (rm -r a folder). No trash — it's gone. Be careful
mkdir nameMake a folder (mkdir -p a/b/c makes the whole chain)
touch fileCreate an empty file (or update its timestamp)
cat filePrint a whole file; less file pages through a long one (q quits)
head / tailFirst / last lines of a file; tail -f follows a growing log live
grep textFind lines matching text (across files with grep -r)
find pathFind files by name, type, age — powerful and a little fiddly
wc / sort / uniqCount lines/words · sort lines · collapse duplicates — the classic text toolkit
ps / killList running processes / stop one by its ID (top shows them live)
chmod / chownChange a file's permissions / owner

#The big idea: small tools, piped together

This is the heart of Unix and the reason the command line is so powerful: each tool does one thing, and you connect them. A pipe (|) feeds one command's output into the next; a redirect (>) sends output to a file. Chain a few and you've built something none of them does alone.

composing commands
$ history | grep git | tail -5      # your last 5 git commands
$ ls -la > listing.txt              # write output to a file (overwrite)
$ echo "a note" >> log.txt           # append to a file
$ cat names.txt | sort | uniq       # sorted, de-duplicated list
a | bPipe — send a's output into b as its input
> fileSend output into a file, replacing it
>> fileAppend output to the end of a file
< fileFeed a file in as a command's input

#Permissions & sudo

Every file records who may read, write, and execute it. You'll mostly meet this in two places: making a script executable, and being told "permission denied." chmod +x file grants the run permission. And sudo runs a single command as the all-powerful "root" admin — necessary sometimes, but pause and read any command you're about to sudo, because root can change anything.

Two commands to truly respect

rm -rf deletes a folder and everything under it with no undo, and sudo removes the guardrails. They're normal tools — but read them twice before pressing Enter, especially if a path has a variable in it.

#Writing your first script

A shell script is just a file of commands the shell runs top to bottom — the natural next step once you're typing the same sequence repeatedly. Three things make a script: a "shebang" line naming the interpreter, the commands, and the executable permission.

greet.sh
#!/usr/bin/env bash            # the shebang: run this with bash
set -euo pipefail             # stop on errors + unset vars (good habit)

name="${1:-world}"            # first argument, or "world" if none
for i in 1 2 3; do
  echo "hello, $name ($i)"
done
run it
$ chmod +x greet.sh     # make it runnable (once)
$ ./greet.sh Ada        # the ./ means "in this folder"

From there the language grows: variables (name="x", used as $name), conditionals (if), loops (for, while), and functions. The setup's own run_ scripts are real-world examples you can read. Two habits that save hours: start every script with set -euo pipefail, and run it through ShellCheck (linked below) — it catches the classic mistakes before they bite.

#So what is Unix? (and where your Mac fits)

You'll hear "Unix," "Linux," and "macOS" used loosely. Here's the real picture — it explains why some commands you copy from the internet behave differently on a Mac.

One ancestor, two branches

Unix was born at AT&T's Bell Labs in 1969. From it grew two big lineages: the BSD branch (from UC Berkeley) and the System V branch (AT&T's commercial line). Almost every Unix-like system today traces back to one or both.

GNU + Linux = the Linux you hear about

The GNU project (started 1983) rebuilt the Unix tools as free software but lacked a kernel. In 1991 Linus Torvalds released the Linux kernel. GNU's tools + Linux's kernel = a complete free OS, which is why purists call it "GNU/Linux." A distribution ("distro") bundles that into a usable system; the big families:

Debian → UbuntuUbuntu is built on Debian; both install .deb packages with apt. The common beginner default
Fedora → RHELFedora is the fast-moving upstream; Red Hat Enterprise Linux is the stable downstream. Use dnf/rpm
ArchIndependent and "rolling release" (always latest); package manager pacman. Minimal, build-it-yourself

macOS: a real Unix, but not Linux

Your Mac's core is Darwin, built on the XNU kernel — a hybrid of the Mach microkernel and a big helping of BSD. That BSD heritage came to Apple from NeXTSTEP (acquired in 1997). The surprising part: macOS is an officially certified UNIX — it passes The Open Group's UNIX specification, which Linux itself does not. So macOS is genuinely "UNIX," while Linux is "Unix-like." But they share no kernel — macOS is not Linux.

What this means for you, practically

Because macOS ships the BSD versions of the classic tools while most online tutorials assume the GNU (Linux) versions, a few commands take different flags. The ones that actually bite:

sed -iOn a Mac it needs an argument: sed -i '' 's/x/y/' file (the '' = no backup). On Linux it's just sed -i 's/x/y/' file
dateMac: date -v-1d for "yesterday"; Linux: date -d "-1 day"
readlink -fGNU-only — not on stock macOS
Filenames' caseThe Mac's default filesystem treats File.txt and file.txt as the same name; Linux treats them as different — a real gotcha when sharing repos
The common fix: GNU tools on your Mac

If you want the Linux behavior, install the GNU versions: brew install coreutils gnu-sed findutils grep. Homebrew names them with a g prefix (gsed, gdate, gls) so they don't shadow the system ones. Also worth knowing: your Mac's default shell has been zsh since macOS Catalina (2019), and the built-in /bin/bash is frozen at an ancient 3.2 — brew install bash if you need a modern one.

#Practice

1

Compose a pipeline

Run ls -la /usr/bin | wc -l to count the programs in a folder. Then history | grep cd | tail -3. Notice you're building new tools out of small ones — that's the whole game.

2

Write and run a script

Save the greet.sh above with nvim greet.sh, chmod +x greet.sh, then ./greet.sh yourname. Change the loop, run it again. You just automated something.

3

Play Bandit

Spend an hour on OverTheWire: Bandit — a game where each level teaches a real command (ls, cat, grep, find, ssh) to unlock the next. The single best hands-on way to get fluent.

#Going deeper

Learn the basics:

Shell scripting:

Practice & drills: