A Field Guide

The Terminal

Everything you need to feel at home on the command line. Navigation, files, scripts, and the mental model that makes it all click.

🧠 Mental Model: How it works
⌨️ Core Skills: Navigate, create, search
⚡ Power Tools: Pipes, env, processes

Why the Terminal Still Matters (and Why Now More Than Ever)

Most people learn to avoid the terminal. It looks intimidating, the errors are cryptic, and graphical apps seem to do everything you need. So why bother?

Three reasons.

Speed. A few keystrokes does what would take a minute of clicking through menus and windows. Once the commands are in your fingers, you operate an order of magnitude faster — especially for repetitive tasks.

Precision. Graphical apps make choices for you. The terminal doesn't. You tell it exactly what to do, and it does exactly that. This is uncomfortable at first, but it means you understand what's actually happening to your files, your projects, your system.

The AI reason. This is the new one. Almost every serious AI development tool — Claude Code, LangChain, local model runners like Ollama, automation frameworks like n8n — lives in the terminal or requires you to be comfortable there. Installing packages, setting API keys, running scripts that call AI APIs, managing local models: all of it happens in the terminal. If you want to build things with AI, terminal fluency isn't optional — it's the floor.

The terminal isn't going away. If anything, it's becoming more central as the AI tooling ecosystem matures. The good news: you don't need to master it. You need to be comfortable enough to not panic, to read error messages, to know what command to reach for. That's what this guide gives you.

💡 Tip
This guide is a 30-minute read. By the end, you'll be able to navigate your file system with confidence, create and manage files, run scripts, search and filter output, customize your setup, and understand what's actually happening when things go wrong.
Part One
The Mental Model
What the terminal actually is, how it thinks, and why the commands look the way they do.

What the Terminal Actually Is

The terminal is a text interface to your computer. Everything you can do by clicking in Finder — moving files, opening folders, running programs — you can do by typing. The terminal skips the visual layer and talks to the operating system directly.

It was invented in the 1970s for Unix mainframes, where users connected via text-only terminals (no screens, just keyboards and printers). The commands were kept brutally short to save keystrokes. That's why ls lists files instead of list, why cd changes directory instead of change-directory. These abbreviations are 50 years old and never changed. Once you know them, they're fast. Before you know them, they feel like a foreign language.

On macOS, the terminal runs a shell called zsh (Z shell). The shell is the program that reads what you type and runs it. Terminal and shell are often used interchangeably in conversation, but technically: the Terminal app is the window, and zsh is what runs inside it — the interpreter that turns your typed commands into action.

📝 Think of it this way
The Terminal app is the TV. The shell (zsh) is the channel you're watching. Other shells exist — bash, fish, sh — but zsh is the macOS default since 2019 and what this guide covers.

The Conversation Model

Think of the terminal as a conversation. You type a command, press Enter, the computer responds, then waits for you to type again. The blinking cursor is the computer saying "I'm listening."

Some commands produce output you can see. Others do their work silently and just return the prompt — silence means success in the terminal. An error will tell you what went wrong. A successful command often says nothing at all.

This is different from graphical apps, which give you constant feedback — spinners, progress bars, confirmations. The terminal trusts you. It assumes you knew what you asked for.

💡 Tip
If you run a command and nothing happens — no error, no output, just a new prompt — that almost always means it worked. Don't panic at the silence.

The Anatomy of a Command

Every command has the same structure:

command [options] [target]
  • command — the program you want to run (ls, cd, mkdir, git)
  • options (flags) — modifiers that change how it runs, usually start with -
  • target — what to run it on: a file, a folder, a URL
ls                        # just the command
ls -l                     # command + option
ls -l ~/Documents         # command + option + target
git commit -m "update"    # command + subcommand + option + value

Flags can usually be combined: ls -la is the same as ls -l -a. Long-form flags use two dashes: --help, --version. These are more readable and appear in documentation.

The Prompt

When you open Terminal, you see something like:

username@computername ~ %

This is the prompt. It shows your username, the computer name, your current location (~ means home directory), and % which signals zsh is ready. You never type the % — just type after it.

⚠️ Important
When documentation shows example commands starting with $ or %, those are prompt symbols — don't type them. Just type the command that follows.

Where You Are: The Home Directory

When Terminal opens, you start in your home directory — the same folder as your user account. Its shorthand is ~.

So ~/Documents means "the Documents folder inside your home directory." On macOS, the full path is something like /Users/yourname, so ~ and /Users/yourname are interchangeable.

Everything you do in the terminal happens somewhere in the file system. Knowing where you are is the most fundamental skill. pwd tells you instantly.

✅ Try It
Open Terminal (Cmd+Space, type "Terminal", press Enter). You'll see the prompt. Type pwd and press Enter. That's your home directory. You're oriented.
Part Two
Navigation — Getting Around
The commands you'll use every single time you open a terminal. Muscle memory within a week.

pwd — Where Am I?

pwd
# outputs: /Users/yourname/Documents/myproject

Print Working Directory. Your current location. Run this whenever you're disoriented.

ls — What's in Here?

ls                    # basic list
ls -l                 # long format: shows size, date modified, permissions
ls -a                 # show all files including hidden ones (starting with .)
ls -la                # both — the most useful form
ls ~/Documents        # list a specific folder without navigating to it
ls -lh                # long format with human-readable file sizes (KB, MB)

The -la form is what you'll use most. It shows everything, including hidden files like .env and .zshrc, which are invisible in Finder but critically important when working on projects.

💡 Tip
Hidden files (starting with .) are everywhere in development — .git, .env, .zshrc, .gitignore. If you're looking for something and can't find it, you're probably not listing hidden files. Always use ls -la.

cd — Move Somewhere Else

cd Documents              # go into Documents (relative to where you are)
cd ~/Documents            # go to Documents from anywhere (absolute)
cd ..                     # go up one level
cd ../..                  # go up two levels
cd ~                      # go home from anywhere
cd -                      # go back to where you just were (toggle)
cd "My Folder"            # quote folder names that have spaces

The cd - trick is underused. If you navigate deep into a folder to do something, then need to go somewhere else entirely, cd - snaps you back. It's a two-location toggle.

✅ Try It
Navigate into a folder: cd Documents. Check where you are: pwd. Go back home: cd ~. Check again: pwd. Now type cd - — you're back in Documents. That's the toggle.

Tab Completion — Your Most Important Habit

Before you type out any path, press Tab. The terminal autocompletes. If there's only one match, it fills in the rest immediately. If there are multiple matches, press Tab twice to see options.

cd Doc[Tab]               # autocompletes to "Documents" if it's the only match
cd Do[Tab][Tab]           # shows: Documents/ Downloads/ Desktop/

Build this habit early. It prevents typos, saves time, and teaches you what's actually in your file system. Most experienced terminal users hit Tab almost automatically — after a slash, after a couple of characters, constantly.

📝 Drag to Paste a Path
In macOS Terminal and iTerm2, you can drag any file or folder from Finder into the terminal window. It pastes the full absolute path. This is enormously useful when you're not sure how to spell a long nested path or when there are spaces in folder names.
Part Three
Files and Folders
Creating, copying, moving, deleting, and viewing — the everyday operations.

Creating Things

mkdir — Make a New Directory

mkdir myproject
mkdir -p projects/fieldguides/terminal    # create nested folders in one command

The -p flag (parents) creates any intermediate directories that don't exist yet. Without it, mkdir projects/fieldguides/terminal would fail if projects or fieldguides don't already exist.

touch — Create a New Empty File

touch index.html
touch .env
touch README.md

touch is technically "update the modification timestamp" but in practice it's used almost exclusively to create new empty files. If the file already exists, it just updates the timestamp without changing the content.

Copying and Moving

cp — Copy a File or Folder

cp original.txt copy.txt              # copy in the same folder
cp notes.txt ~/Desktop/               # copy to a different location
cp -r myfolder/ backup/               # copy a folder and all its contents (-r = recursive)

mv — Move or Rename

mv oldname.txt newname.txt            # rename (same location, new name)
mv file.txt ~/Documents/              # move to a different folder
mv myfolder/ ~/Documents/myfolder/    # move a folder

mv is the same command for both renaming and moving — the distinction is just whether the destination is in the same folder or a different one.

Deleting — Read This Carefully

rm file.txt                           # delete a single file
rm file1.txt file2.txt file3.txt      # delete multiple files
rm -r myfolder/                       # delete a folder and everything in it
rm -i file.txt                        # interactive: asks you to confirm each deletion
⚠️ Warning
There is no trash can. There is no undo. rm is permanent. This is one of the few places in the terminal where you need to slow down and double-check.

A few rules:

  • Always check your current location with pwd before a recursive delete
  • Use ls to confirm what's in a folder before rm -r-ing it
  • Consider using rm -i for important deletions — it makes you confirm each file
  • Never run commands that include rm -rf / or rm -rf ~ — these are catastrophic

Viewing File Contents

cat — Print to Screen

cat notes.txt
cat .env
cat package.json

Good for short files. For anything long, it scrolls past too fast to read.

less — View Page by Page

less longfile.txt
less README.md

Navigation inside less: Space to go forward, b to go back, / followed by a word to search, n to find the next match, q to quit. This is how you read log files, long documentation, anything that doesn't fit on a screen.

head and tail — See the Beginning or End

head -20 logfile.txt      # first 20 lines
tail -20 logfile.txt      # last 20 lines
tail -f logfile.txt       # keep watching the file as it grows (great for logs)

tail -f is particularly useful when running a server or AI script — you can watch the output log in real time in one terminal window while working in another.

open — Open in macOS's Default App

open .                              # open current folder in Finder
open file.pdf                       # open in Preview
open -a "Sublime Text" file.txt     # open in a specific application
open https://fieldguides.tech       # open a URL in your browser
Part Four
Paths — The Address System
Understanding paths is the single thing that makes the terminal click.

Absolute Paths

An absolute path starts from the very root of the file system, always beginning with /. The root is the top level — above everything else.

/Users/yourname/Documents/myproject/index.html

Read this left to right: start at root (/), go into Users, into yourname, into Documents, into myproject, find index.html. This path works from anywhere — it's the full address, like a street address including country.

Relative Paths

A relative path starts from wherever you currently are. If you're already in /Users/yourname/Documents, then:

myproject/index.html      # means: Documents/myproject/index.html
../photos/                # means: go up from Documents, then into photos/

Two special relative path symbols:

  • . — the current directory (used a lot: open ., ls .)
  • .. — the parent directory (go up one level)

The ~ Shortcut

~ always expands to your home directory's absolute path. So these are equivalent:

~/Documents/myproject
/Users/yourname/Documents/myproject

Use ~ in your commands — it's shorter and works regardless of username.

💡 Why Paths Matter for AI Projects
When you work with AI tools, you're constantly pointing programs at files: "here's my data file," "here's my script," "here's where to save the output." Getting paths wrong is the single most common source of "file not found" errors. Understanding absolute vs. relative paths, knowing how to use pwd to confirm where you are, and using Tab completion to avoid typos eliminates most of these.
Part Five
Searching and Filtering
Find text inside files, locate files by name, and count things.

grep — Find Text Inside Files

grep searches for a pattern inside files and prints every line that matches.

grep "API_KEY" .env                   # find lines containing "API_KEY" in .env
grep "error" logs.txt                 # find error lines in a log file
grep -i "error" logs.txt              # case-insensitive (-i)
grep -r "fieldguides" ./guides/       # search recursively through all files (-r)
grep -n "function" script.py          # show line numbers with matches (-n)
grep -v "debug" logs.txt              # show lines that DON'T match (-v = invert)
grep -c "error" logs.txt              # just count the matches (-c)

grep becomes powerful when combined with other commands via pipes (Part 6). It's also one of the first AI-workflow tools — when your AI script produces hundreds of lines of output, grep lets you extract exactly the lines you care about.

find — Locate Files by Name or Property

find . -name "*.html"                 # find all .html files in current folder and below
find ~/Documents -name "*.md"         # find markdown files in Documents
find . -name ".env" -type f           # find files named exactly .env
find . -mtime -7                      # files modified in the last 7 days
find . -size +10M                     # files larger than 10MB

find is slower than grep but operates on filenames and file properties rather than contents. Good for tracking down where a file ended up when you can't remember.

wc — Count Words, Lines, Characters

wc -l file.txt                        # count lines
wc -w file.txt                        # count words
cat logs.txt | wc -l                  # count how many log lines there are

Useful for sanity-checking data: "how many rows does this CSV have?" or "how many lines did my script produce?"

Part Six
Pipes and Chaining
Where the real power is. Small tools, combined.

The Unix Philosophy

The tools that come with the terminal are small and do one thing well. ls lists files. grep filters lines. wc counts things. None of them tries to do everything.

The power comes from combining them — passing the output of one command as the input to the next. This is the Unix philosophy, and it's still elegant 50 years later.

Pipes |

The pipe character | takes the output of the command on the left and feeds it as input to the command on the right.

ls -la | grep ".html"              # list files, then keep only lines mentioning .html
cat logs.txt | grep "error"        # show logs, filter to error lines only
ls -la | wc -l                     # count how many files are in the current folder
history | grep "git"               # find git commands you've run recently
cat data.csv | wc -l               # count rows in a CSV

You can chain as many pipes as you want:

cat server.log | grep "error" | grep -v "404" | wc -l
# read the log, keep error lines, remove 404 errors, count what's left

Redirect to Files

> saves command output to a file (overwrites if it exists):

ls -la > filelist.txt              # save directory listing to a file
python3 script.py > output.txt     # save script output to a file

>> appends to a file without overwriting:

echo "run complete" >> run-log.txt
python3 script.py >> output.txt    # add this run's output to existing file

2> redirects error output (stderr) separately:

python3 script.py > output.txt 2> errors.txt    # output and errors to separate files
python3 script.py > output.txt 2>&1              # combine output and errors into one file

Chaining Commands

&& — run the second command only if the first succeeded:

git add . && git commit -m "update" && git push
mkdir myproject && cd myproject && touch index.html

This is how you write reliable sequences. If git add fails, the commit never runs. If the commit fails, the push never runs.

; — run commands in sequence regardless of success or failure:

cd myproject ; ls

|| — run the second command only if the first failed:

mkdir myproject || echo "folder already exists"
💡 Why This Matters for AI Workflows
AI scripts tend to produce a lot of output — API responses, log messages, intermediate results, errors. Pipes and redirects let you tame that output: save it to files for later, filter it to find what went wrong, count how many items were processed. When you're running an AI agent that processes 500 documents and you want to know how many produced errors, grep "error" output.log | wc -l gives you the answer instantly.
Part Seven
Environment Variables and .zshrc
How programs find their settings, and how you customize your shell.

What Environment Variables Are

Environment variables are named values your shell keeps in memory. They configure how programs behave.

echo $PATH              # see your current PATH
echo $HOME              # your home directory
echo $SHELL             # which shell you're running
echo $USER              # your username

The $ prefix tells the shell "this is a variable, show me its value."

Why This Matters: API Keys

Environment variables are how you securely pass API keys and secrets to programs without hardcoding them in your code. When you see instructions like "set your ANTHROPIC_API_KEY environment variable," this is what they mean.

export ANTHROPIC_API_KEY="sk-ant-..."

You can set a variable for just the current session (as above), or permanently in your .zshrc. Programs that need the key read it from the environment — they never see it written in your code. For why this matters and what happens when secrets leak, see the Security field guide.

.zshrc — Your Shell's Config File

Every time you open a new terminal window, zsh reads ~/.zshrc and runs everything in it. This file is your shell's personal configuration.

It's where you put:

  • Environment variables and API keys
  • PATH additions (so the shell can find new programs)
  • Aliases (custom shortcuts)
  • Plugin configurations
nano ~/.zshrc           # open your config file in the nano editor
source ~/.zshrc         # reload it after making changes, without restarting terminal
⚠️ Security Note
Your .zshrc contains secrets. It's a hidden file (starts with .) that Finder doesn't show by default. Never commit it to a public GitHub repo. If you want to back it up, use a private repo or a secure notes app.

Aliases — Building Your Personal Shorthand

Aliases are your own custom commands. After you add them to .zshrc and run source ~/.zshrc, they work exactly like built-in commands.

alias ll='ls -la'
alias gs='git status'
alias gp='git push'
alias gl='git log --oneline -10'
alias ..='cd ..'
alias ...='cd ../..'
alias reload='source ~/.zshrc'
alias serve='python3 -m http.server 8080'
alias myip='curl -s ifconfig.me'

The serve alias is a good example of real-world value: python3 -m http.server 8080 starts a local web server in the current folder, serving files at localhost:8080. It's how you preview static HTML files locally. You don't want to type that every time.

PATH — How the Shell Finds Programs

When you type git or python3 or claude, the shell searches through a list of directories in order until it finds a program with that name. That list is PATH.

If a program isn't in PATH, the shell says "command not found." After installing new software, you often need to add its directory to PATH:

export PATH="/opt/homebrew/bin:$PATH"          # Homebrew (macOS)
export PATH="$HOME/.local/bin:$PATH"           # Python user installs
export PATH="/usr/local/go/bin:$PATH"          # Go language

The :$PATH at the end means "add this in front of the existing PATH" — you're prepending, not replacing. Order matters: the shell searches left to right, so directories earlier in PATH take priority.

Part Eight
Processes — Running and Stopping Programs
Scripts, background jobs, and the keyboard shortcuts you'll use daily.

Running Scripts

python3 script.py                     # run a Python script
node app.js                           # run a Node.js application
bash myscript.sh                      # run a shell script
./myscript.sh                         # run directly (needs execute permission first)
claude                                # start Claude Code

When you run a script, your terminal is "occupied" — the prompt doesn't come back until the script finishes. You can open a new terminal tab or window to do other things while it runs.

Making a Script Executable

Shell scripts need execute permission before you can run them with ./:

chmod +x myscript.sh                  # give it execute permission
./myscript.sh                         # now you can run it directly

Stopping Things

  • Ctrl+C — interrupt and stop the currently running process. Your most-used kill switch.
  • Ctrl+Z — pause (suspend) the process and send it to the background
  • q — quit interactive programs like less, man, git log
  • exit or Ctrl+D — close the current shell session
💡 Tip
If a program seems frozen and Ctrl+C isn't working, try Ctrl+\ (a stronger interrupt signal). As a last resort, close the terminal tab.

Background Jobs

python3 server.py &          # & at the end runs the process in the background
                              # you get the prompt back immediately

jobs                          # list all background jobs
fg                            # bring the last background job to foreground
fg %2                         # bring job number 2 to foreground
bg                            # resume a paused (Ctrl+Z) job in the background
kill %1                       # kill job number 1

Running things in the background is useful when you need a server or watcher running while you do other work in the same terminal window.

Checking What's Running

ps aux                        # list all running processes
ps aux | grep python3         # find python3 processes specifically
top                           # live activity monitor (press q to quit)

top is the terminal equivalent of Activity Monitor — you can see what's eating CPU and memory. Press q to exit.

Part Nine
Working with Text
Editing files, printing values, and find-and-replace from the command line.

nano — Simple In-Terminal Text Editor

nano is a text editor that runs inside the terminal. It's not powerful, but it's approachable — unlike vim, you don't need to know any special commands to start typing and save.

nano .zshrc                   # open a file for editing
nano notes.txt                # create and edit a new file

Inside nano:

  • Just type to edit
  • Ctrl+O then Enter — save the file
  • Ctrl+X — exit (will ask if you want to save unsaved changes)
  • Ctrl+W — search for a word
  • Ctrl+K — cut the current line
  • Ctrl+U — paste

The shortcuts are shown at the bottom of the nano window — the ^ symbol means Ctrl.

echo — Print Text or Variable Values

echo "Hello world"            # print text
echo $PATH                    # print a variable's value
echo $ANTHROPIC_API_KEY       # confirm an API key is set (shows the value)
echo "done" >> log.txt        # append text to a file

echo is simple but useful for debugging: "is this environment variable actually set?" echo $VARIABLE_NAME tells you instantly.

sed — Find and Replace in Files

sed (stream editor) can find and replace text inside files without opening an editor:

sed 's/old/new/g' file.txt                        # print with replacements (doesn't change file)
sed -i '' 's/old/new/g' file.txt                  # replace in-place (macOS syntax)
sed 's/http:/https:/g' config.txt                 # replace all http: with https:

The s/old/new/g pattern means: substitute old with new, globally (all occurrences). sed is useful for quick batch text replacements — changing a URL throughout a config file, fixing a variable name across a script.

Part Ten
Useful Commands You'll Actually Use
The commands that come up constantly in real work, especially AI-adjacent projects.

Getting Help

man — The Manual

man ls                        # full documentation for ls
man grep                      # full documentation for grep
# press q to quit, / to search within the man page

--help — Quick Summary

git --help
python3 --help
ls --help

Most commands support --help. It's faster than man when you just need to remind yourself what a flag does.

Finding Things

which — Where Is a Program Installed?

which python3                 # /usr/bin/python3
which node                    # /opt/homebrew/bin/node
which claude                  # confirms Claude Code is installed and in PATH

If which returns nothing, the program isn't installed or isn't in your PATH.

history — Your Command History

history                       # list all recent commands with numbers
history | grep "python"       # find python commands you've run
history | tail -20            # last 20 commands
!42                           # re-run command number 42 from history
!!                            # re-run the very last command
sudo !!                       # re-run the last command with sudo

The !! trick is particularly useful: you run a command, get "permission denied," then sudo !! runs it again as administrator without retyping.

Network and HTTP

curl — Make HTTP Requests

curl https://api.example.com/data                     # basic GET request
curl -X POST https://api.example.com/items \
  -H "Content-Type: application/json" \
  -d '{"name": "test"}'                               # POST with JSON body
curl -H "Authorization: Bearer $API_KEY" https://...  # authenticated request
curl -o output.json https://api.example.com/data      # save response to file

curl is the terminal's HTTP client. For AI development, you'll use it to test API endpoints, download datasets, and verify that your API keys work before writing code.

ping — Check If a Server Is Reachable

ping google.com               # Ctrl+C to stop

Disk and File Sizes

du -sh myfolder/              # total size of a folder, human-readable
du -sh */                     # size of each subfolder in current directory
df -h                         # show disk space on all drives, human-readable

Other Useful Ones

clear — clean the terminal screen. Or press Cmd+K on Mac, which also clears the scrollback.

whoami — your current username. Useful in scripts to confirm what user is running them.

date — current date and time. Useful for timestamping log entries.

sleep — pause for a number of seconds. Used in scripts: sleep 5 waits 5 seconds.

pbcopy and pbpaste (macOS)

cat file.txt | pbcopy             # copy file contents to clipboard
echo $API_KEY | pbcopy            # copy an API key to clipboard
pbpaste > newfile.txt             # paste clipboard contents into a file

pbcopy is underrated. Pipe any command's output directly to clipboard and paste it wherever you need it.


iTerm2 — A Better Terminal App

The default macOS Terminal works fine. But most developers switch to better tools quickly. iTerm2 is free and replaces the default Terminal app.

Key advantages:

  • Split panes — run multiple terminal sessions side by side in one window
  • Better search — search through your terminal history visually
  • Profiles — different color schemes for different contexts (red for production, blue for local)
  • Triggers — highlight lines that match patterns (great for spotting errors in logs)

Download from iterm2.com and use it exactly like Terminal. The learning curve is zero — everything works the same, just better.

Homebrew — The Package Manager for macOS

Homebrew is to macOS what npm is to Node.js: it installs and manages software from the command line.

Install Homebrew:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Then:

brew install python               # install Python
brew install node                 # install Node.js
brew install wget                 # install wget
brew install ffmpeg               # install ffmpeg (audio/video processing)
brew list                         # see what you've installed
brew update && brew upgrade       # update everything
brew search [name]                # find a package

For macOS apps: brew install --cask iterm2, brew install --cask visual-studio-code. Homebrew manages GUI apps too.

Oh My Zsh — Enhance Your Shell

Oh My Zsh is a framework that adds features and plugins to zsh.

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

The two plugins worth adding immediately. Edit ~/.zshrc to find the plugins= line:

plugins=(git zsh-autosuggestions zsh-syntax-highlighting)

zsh-autosuggestions — as you type, it shows a ghost completion from your history. Press the right arrow to accept it. This alone saves enormous amounts of retyping.

zsh-syntax-highlighting — colors your command as you type. Commands that exist turn green. Typos stay red. You catch errors before running them.

git plugin (included with Oh My Zsh) — adds shorthand aliases for common git commands: gst for git status, gp for git push, gcb for git checkout -b. Run alias | grep git to see them all.

A Practical .zshrc for AI Builders

A starting point — adapt it to your setup:

# Homebrew (M1/M2 Macs)
export PATH="/opt/homebrew/bin:$PATH"

# Python (if installed via Homebrew)
export PATH="/opt/homebrew/opt/[email protected]/bin:$PATH"

# API keys — never commit this file to git
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-proj-..."

# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="robbyrussell"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
source $ZSH/oh-my-zsh.sh

# Autosuggestions (if installed via Homebrew)
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh

# Aliases — navigation
alias ll='ls -la'
alias ..='cd ..'
alias ...='cd ../..'
alias reload='source ~/.zshrc'
alias proj='cd ~/projects'

# Aliases — git
alias gs='git status'
alias gp='git push'
alias gl='git log --oneline -10'

# Aliases — utilities
alias serve='python3 -m http.server 8080'
alias myip='curl -s ifconfig.me'
alias ports='lsof -i -P -n | grep LISTEN'

Troubleshooting — Reading What the Terminal Tells You

Error messages in the terminal are more helpful than they look. Most of them fall into a handful of patterns.

"command not found"

zsh: command not found: claude

The program isn't installed, or it's installed but not in your PATH.

  1. Check if it's installed: which claude — if nothing comes back, it's not in PATH
  2. If you just installed something, check if you need to add it to PATH in .zshrc
  3. If you used Homebrew, try brew link [packagename]
  4. Close and reopen the terminal (new installs sometimes require this)

"permission denied"

permission denied: ./myscript.sh

You don't have permission to run or access the file. Try:

  • For scripts: chmod +x myscript.sh then try again
  • For system operations: prefix with sudo (use sparingly — sudo runs as administrator)

"no such file or directory"

cat: myfile.txt: No such file or directory
  1. pwd — are you where you think you are?
  2. ls — is the file actually there? (check spelling)
  3. Did you forget to navigate into the right folder first?
  4. Is there a typo in the path? Tab completion prevents this.

Terminal Seems Frozen

The program is either still running, waiting for input, or genuinely stuck.

  • Try pressing Enter (some programs wait for you to press Enter)
  • Try Ctrl+C to interrupt
  • Try q to quit
  • Try Ctrl+Z to suspend
  • As a last resort, close the terminal tab

Changes to .zshrc Aren't Working

You edited .zshrc but new aliases or variables don't work. You need to reload it:

source ~/.zshrc

Or close and reopen the terminal. Changes to .zshrc only take effect in new sessions, or after reloading.

Reading Error Messages Like a Developer

Most terminal error messages follow a pattern: what failed, why it failed, sometimes a hint. Read them carefully before assuming they're cryptic. Google the exact error message — in quotes — if you don't understand it.

💡 Tip
When using Claude Code or other AI tools, paste the full error message. Not "it doesn't work" — the full output from the terminal. That's the information the AI needs to help you.

The Terminal and AI Development — The Full Picture

It's worth pausing to connect what you've learned to the AI tools you might build with.

Claude Code lives entirely in the terminal. It reads your files, writes code, runs commands, commits to git — all from the terminal. Your comfort level here directly determines how much you can delegate to it.

Running local models (Ollama, LM Studio's CLI mode) happens in the terminal. You pull a model, run it, point it at data — all commands.

Python and Node projects for AI — calling APIs, building agents, processing data — are started, configured, and debugged from the terminal. Your .env files with API keys are read by these programs. Your PATH determines whether python3 finds the right Python version.

Automation scripts — the kind that run on a schedule, process files, call APIs, generate reports — all live and run in the terminal. Pipes and redirects let you chain them together.

Log files and debugging — when an AI script runs for 10 minutes and produces an error, grep, tail -f, and wc -l are your triage tools. They let you interrogate output without reading every line.

📝 The Big Picture
The terminal is the connective tissue of the modern AI builder's workflow. Not glamorous, not visual — but everything runs through it.

Quick Reference Cheat Sheet

Navigation

CommandWhat it does
pwdWhere am I?
ls -laList everything including hidden files
cd foldernameGo into a folder
cd ..Go up one level
cd ~Go home
cd -Toggle back to previous location

Files

CommandWhat it does
mkdir nameCreate a folder
mkdir -p a/b/cCreate nested folders
touch file.txtCreate an empty file
cp a.txt b.txtCopy a file
mv a.txt b.txtMove or rename
rm file.txtDelete a file (permanent)
rm -r folder/Delete a folder (permanent)

Viewing Content

CommandWhat it does
cat file.txtPrint file to screen
less file.txtView file page by page (q to quit)
head -20 file.txtFirst 20 lines
tail -f file.txtWatch file grow in real time
grep "word" fileFind lines containing a word
grep -r "word" ./Search recursively through a folder

Power Tools

CommandWhat it does
cmd1 | cmd2Pipe output of cmd1 into cmd2
cmd > file.txtSave output to file (overwrite)
cmd >> file.txtAppend output to file
cmd1 && cmd2Run cmd2 only if cmd1 succeeds
cmd &Run in background

Shell Config

CommandWhat it does
source ~/.zshrcReload shell config
echo $VARIABLEPrint a variable's value
export VAR="val"Set an environment variable
which programFind where a program is installed
history | grep XFind past commands matching X

Keyboard Shortcuts

ShortcutWhat it does
TabAutocomplete
Up / DownNavigate command history
Ctrl+CStop current process
Ctrl+ZPause current process
Ctrl+L / Cmd+KClear screen
!!Repeat last command
sudo !!Repeat last command as admin
You're Ready.
The terminal isn't going away. Now you know how to use it.