Skip to main content

⌨️ Terminal / Command Line Introduction

The terminal looks intimidating and turns out to be the single biggest productivity multiplier a developer can learn. This lesson demystifies the shell, teaches the handful of commands you'll use every day, and shows how pipes and redirection let you combine small tools into powerful one-liners.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Explain what a shell is and how it reads, runs, and returns the result of a command
  • Navigate the filesystem and manage files with cd, ls, mkdir, cp, mv, and rm
  • Translate common commands between Windows, macOS, and Linux
  • Combine commands with pipes and redirection to build small data pipelines
  • Apply history, tab-completion, and keyboard shortcuts to move quickly and safely

Estimated Time: 40–50 minutes  •  Difficulty: Beginner

Hands-on: Scaffold a project tree and answer real questions about a log file using only the terminal.

In This Lesson

Why the Terminal Matters

A terminal (or command-line interface) is a text-based way to tell your computer exactly what to do. Graphical interfaces are friendly, but they hide power behind menus and only do what a designer anticipated. The terminal does anything the system can do — and it does it fast, repeatably, and scriptably.

💡 Analogy: A GUI is a restaurant menu — convenient, but you can only order what's printed. The terminal is walking into the kitchen and cooking whatever you like. Slightly scarier, infinitely more capable.

Three concrete reasons developers live in the terminal:

  • Speed: "find every JavaScript file changed this week that mentions fetch" is one line instead of a dozen clicks.
  • Automation: anything you can type, you can save as a script and run again forever.
  • It's how the tools work: Git, npm, Docker, deployment pipelines, and remote servers are all driven from the command line.

How the Shell Works

The program that reads your typed commands is called a shell. On Linux and modern macOS it's usually Bash or Zsh; on Windows it's PowerShell. The loop is always the same: it prints a prompt, you type a command, it runs the command, prints any output, and prompts again.

The read-evaluate-print loop of a shell You type a command at the prompt; the shell interprets it, runs the matching program, and prints the result back to the terminal before showing the prompt again. You type a command Shell parses & runs it Terminal prints output new prompt — ready for the next command
Figure 1 — The shell's read-run-print loop. Every command follows this same cycle, which is why the terminal feels predictable once it clicks.

A command has up to three parts: the command itself, optional options (flags, usually starting with -), and optional arguments (what to act on):

ls   -la   /home/ray
# │    │      │
# │    │      └─ argument: which directory to list
# │    └──────── options: -l long format, -a include hidden files
# └───────────── command: "list directory contents"

📖 Key Terms

Shell: the program that interprets your commands (Bash, Zsh, PowerShell).

Prompt: the text the shell shows when it's ready for input (often ends in $ or >).

Working directory: the folder your commands act on "right now" — shown by pwd.

Working With Files

Creating, copying, moving, and deleting files are the bread-and-butter operations. Here are the ones you'll use constantly:

# Create
touch notes.txt                 # create an empty file
mkdir app                       # create a directory
mkdir -p app/src/components      # create nested dirs in one shot

# Inspect
cat notes.txt                    # print a file's whole contents
less server.log                  # scroll a big file (q to quit)
head -n 20 data.csv              # first 20 lines
tail -n 20 data.csv              # last 20 lines
tail -f server.log               # follow a log live as it grows

# Copy / move / rename
cp notes.txt notes.bak           # copy
cp -r app app-backup             # copy a directory recursively
mv notes.txt docs/notes.txt      # move
mv old-name.txt new-name.txt     # rename (same command)

# Delete
rm notes.bak                     # remove a file
rm -r app-backup                 # remove a directory and its contents

⚠️ rm has no undo

There is no Recycle Bin on the command line. rm -r deletes permanently and immediately. Double-check the path before you press Enter, and be extremely careful with wildcards — rm -rf * in the wrong directory is a genuine disaster. When unsure, ls the pattern first to see what it matches.

Commands Across Operating Systems

The classic Unix commands (ls, cat, cp…) work identically on macOS and Linux. Windows PowerShell uses different native command names but provides aliases so many Unix commands still work:

Action macOS / Linux Windows PowerShell
List directorylsGet-ChildItem (alias ls/dir)
Change directorycdSet-Location (alias cd)
Working directorypwdGet-Location (alias pwd)
Show file contentscatGet-Content (alias cat)
Copy filecpCopy-Item (alias cp)
Delete filermRemove-Item (alias rm)
Path separator/\ (but / often works too)

✅ The pragmatic solution: WSL

Because most servers and deployment platforms run Linux, many Windows developers install the Windows Subsystem for Linux and use a real Ubuntu terminal. One command sets it up:

# Run in an elevated PowerShell, then reboot
wsl --install

Now the Linux commands in this course work byte-for-byte on your Windows machine.

Pipes & Redirection

Here's where the terminal becomes genuinely powerful. The Unix philosophy is "small tools that do one thing well," combined with two operators that connect them:

  • Pipe | — send the output of one command straight into the next as input.
  • Redirect > / >> — send output into a file (overwrite / append) instead of the screen.
# Redirect output into files
echo "node_modules/" > .gitignore     # create/overwrite
echo ".venv/" >> .gitignore            # append a second line

# Pipe: chain small tools into a pipeline
history | grep git                     # find past commands mentioning 'git'
ls -la | wc -l                         # count how many items are here

# A real one-liner: top 5 most common HTTP status codes in a log
cat access.log | cut -d ' ' -f 9 | sort | uniq -c | sort -nr | head -5

Read that last line left to right as an assembly line: cat pours out the log → cut grabs the status-code column → sort groups identical codes → uniq -c counts each group → sort -nr ranks them → head -5 keeps the top five. Each tool is simple; together they answer a real question in one line.

flowchart LR A[cat access.log] --> B[cut column 9] B --> C[sort] C --> D[uniq -c] D --> E[sort -nr] E --> F[head -5]

Speed: History & Shortcuts

Two habits separate slow terminal users from fast ones: never retype, and never mash the arrow keys.

Reuse what you already typed

  • ↑ / ↓ — walk through previous commands.
  • Ctrl + R — reverse-search history; start typing and it finds the last matching command.
  • Tab — autocomplete a command or file name; press twice to see all options.
  • !! — repeat the last command (handy as sudo !! after a permission error).

Move the cursor without arrows

ShortcutDoes
Ctrl + AJump to start of line
Ctrl + EJump to end of line
Ctrl + UDelete to start of line
Ctrl + CCancel the running command
Ctrl + LClear the screen

Make shortcuts of your own: aliases

An alias is a nickname for a longer command. Add these to ~/.bashrc (or ~/.zshrc) and reload with source ~/.bashrc:

# ~/.bashrc
alias ll='ls -alF'
alias gs='git status'
alias gp='git push'
alias ..='cd ..'

Hands-on Exercise

🏋️ Scaffold a project and interrogate a log

Objective: Practice the whole toolkit — directories, files, and a pipeline — with commands only.

Part A — build a project tree

  1. Make a project with nested folders in one command.
  2. Create a few empty files inside it.
  3. List the directory structure to confirm it.
mkdir -p my-site/{css,js,images}
touch my-site/index.html my-site/css/style.css my-site/js/app.js
find my-site -type f | sort

Part B — answer a question with a pipeline

  1. Create a small fake log file.
  2. Use a pipeline to count how many lines contain ERROR.
# Build a tiny log to work with
printf 'INFO ok\nERROR disk\nINFO ok\nERROR net\nWARN slow\nERROR net\n' > app.log

# Question: how many ERROR lines are there?
grep -c ERROR app.log

# Bonus: which error is most common?
grep ERROR app.log | sort | uniq -c | sort -nr
💡 Hint

grep -c counts matching lines directly. For the bonus, remember the pipeline pattern from the pipes section: sort groups identical lines so uniq -c can count each group.

✅ Expected output

grep -c ERROR app.log prints 3. The bonus pipeline shows 2 ERROR net on top and 1 ERROR disk below it — "net" is the most common error.

🎯 Quick Quiz

Question 1: What does the pipe operator | do?

Question 2: You want to create a/b/c where none of those folders exist yet. Which command works?

Question 3: Why is rm -r considered dangerous?

Summary & Quiz

🎉 Key Takeaways

  • The shell runs a simple loop: prompt → command → output → prompt.
  • A command is a command + options + arguments; paths can be absolute or relative.
  • The core file commands (cd, ls, mkdir, cp, mv, rm) are the same on macOS and Linux; WSL brings them to Windows.
  • Pipes and redirection combine small tools into powerful one-liners.
  • History, tab-completion, and aliases are what make experienced users fast.

📚 Further Reading

🚀 What's Next?

You can now move around and manipulate files from the terminal. Next we'll set up the editor where you'll spend most of your time — installing and configuring VS Code so it works hand-in-glove with the command line you just learned.

🎉 You speak shell now!

Keep a terminal open beside every project — it'll soon feel faster than reaching for the mouse.