ap.Abhishek Patel

Search

Search notes, essays, projects, the library and the AI course. Use arrow keys to choose and Enter to open.

Lesson 1 of 5 30 min Beyond the syllabus

The terminal without fear

Navigate folders, handle files, chain commands with pipes and set environment variables in the terminal, on macOS, Linux or Windows.

Words in this lessonTerminal · Shell · Working directory · File path · Pipe · Environment variable · PATH
Terminal
A text window where you type exact instructions to your computer instead of clicking. Like the kitchen's back door where staff call out exact orders, compared with the shop front's picture menu.
Shell
The program inside a terminal that reads your commands and runs them. Like the kitchen assistant who hears your instructions and carries them out, in their own dialect.
Working directory
The folder your terminal is currently "standing in", which commands run from. Like the room an assistant is standing in: "fetch the butter from the second shelf" depends entirely on which room that is.
File path
The address of a file or folder on your computer. Like a postal address: either the full address from the country down, or directions from where you are standing.
Pipe
The `|` symbol, which sends the output of one command into the next command as its input. Like a conveyor belt between two bakery stations, carrying each tray straight from one to the next.
Environment variable
A named value, like ANTHROPIC_API_KEY, that programs started from your shell can read. Like notes pinned on the kitchen noticeboard that every cook on the shift can read.
PATH
The list of folders your shell searches, in order, to find the program you typed. Like the list of storerooms an assistant checks, in order, when you ask for an ingredient by name.
On this page
  1. Why engineers type into a black window
  2. You are always standing somewhere
  3. One command, taken apart
  4. Commands, options and arguments
  5. Moving around and handling files
  6. Environment variables and PATH
  7. Where it breaks
  8. Try it yourself
  9. Common mistakes
  10. Recap
  11. Go deeper

On Monday, Priya drops a folder onto Crumb’s shared drive. It is called support-export, and it holds 412 text files, one per customer email from the week after Diwali.

“Before we build anything clever,” she says, “I want to know how big the refund problem is. How many of these emails mention a refund?”

Meera, passing by, adds: “And I want that number before my 11 o’clock with the store managers.”

It is 10:15. Arjun opens the folder in his file browser and starts double-clicking. Open a file, read it, close it, make a tally mark. By 10:35 he has done 31 files and his tally says 6. At this rate he will finish around 2 p.m. He tries to speed up by skimming, loses count, and starts again.

Priya watches for a minute, then leans over his keyboard, opens a terminal, and types one line:

grep -il refund support-export/*.txt | wc -l

Half a second later the screen says 84.

Arjun stares. “What did you just do?”

“I asked the computer, in its own language, instead of doing its job by hand.”

Important

The idea in one sentence: The terminal is a text window where you type exact instructions to your computer, each one a command run from a particular folder, and once you can read and write those instructions, you can automate in one line what takes hours by clicking.

Why engineers type into a black window

Meera has always wondered this. “Why do all of you type into that black box? Is it just to look clever?”

Priya uses the bakery. “The shop front has a menu with pictures. That is your file browser and your apps: point, click, choose from what is offered. It is friendly, but you can only order what is on the menu. The kitchen has a back door where staff shout exact instructions: ‘Forty croissants, extra butter, out by seven.’ That is the terminal. Nothing is offered to you. You have to know what to ask for. But you can ask for anything, combine instructions, and repeat them perfectly a thousand times.”

For an AI engineer, the back door is not optional. Almost every tool in this course is driven from it: uv to run Python, git to save code, docker to run databases, curl to test APIs. Many AI tools have no menu at all. And when you deploy an app to a server, there is no screen to click on: only a terminal.

Two words people mix up:

  • The terminal is the window: the program that shows text and takes your typing.
  • The shell is the program inside it that actually reads your command and runs it. On macOS the default shell is zsh; on most Linux machines it is bash; on Windows it is PowerShell. They are dialects of the same idea, and most everyday commands work in all three.

When the shell is ready for a command, it shows a prompt: a short line ending in %, $ or >, often with the current folder in it. In examples, we leave the prompt out; type only the command.

You are always standing somewhere

Arjun wants to try it himself. He opens a fresh terminal and types Priya’s exact command. The answer is not 84:

zsh: no matches found: support-export/*.txt

(In bash the message is No such file or directory.) Same command, same computer. What changed?

“Where are you standing?” asks Priya.

“At my desk?”

“Your shell is standing somewhere. Every terminal is always ‘in’ one folder, called the working directory. A new terminal starts in your home folder. My command said support-export/..., which means ‘the support-export folder right here’. There is no support-export folder in your home folder.”

The kitchen version: if you tell an assistant “fetch the butter from the second shelf”, the answer depends entirely on which room they are standing in.

Note

Pause and think. The command cat notes.txt (show the contents of notes.txt) works in one terminal window and fails with “No such file or directory” in another, on the same computer, at the same moment. Give the most likely explanation.

Show the answer

The two windows have different working directories. notes.txt is a relative path: it means “a file called notes.txt in the folder I am currently in”. One window is in the folder that contains it; the other is somewhere else. Run pwd (print working directory) in each window to see. Fix it by moving with cd, or by giving the full path to the file.

One command, taken apart

Arjun moves into the right folder (cd means “change directory”; you will see it properly below) and runs it again. 84. Now Priya takes the command apart, piece by piece, showing what each part produces.

grep -il refund support-export/*.txt | wc -l

Piece 1: support-export/*.txt. Before anything runs, the shell expands the * (a wildcard, meaning “anything”) into every matching filename. So the shell turns this into a list of 412 names: support-export/email-0001.txt, support-export/email-0002.txt, and so on to email-0412.txt.

Piece 2: grep -il refund .... grep is a program that searches text. refund is what to search for. -i is an option (also called a flag) meaning “ignore case”, so “Refund” and “REFUND” count too. -l means “just list the names of files that match, once each”. Run on its own, grep -il refund support-export/*.txt prints:

support-export/email-0003.txt
support-export/email-0005.txt
support-export/email-0010.txt
...

84 lines, one per matching file.

Piece 3: |. The pipe. It takes everything the command on its left would have printed and feeds it, as input, to the command on its right. Nothing appears on screen in between.

Piece 4: wc -l. wc means “word count”; -l means “count lines instead”. It receives 84 lines through the pipe and prints 84. (On macOS it prints a few spaces before the number; that is normal.)

That is the whole trick. Small programs that each do one thing well, joined with pipes. Arjun’s afternoon of clicking became four small, checkable steps.

On Windows PowerShell, the same question is asked like this:

(Select-String -Path support-export\*.txt -Pattern refund -List).Count

Select-String is PowerShell’s search (case-insensitive by default), and -List stops after the first match in each file, so .Count counts files.

Commands, options and arguments

Every command you type has the same shape:

command  -options  arguments
grep     -il       refund support-export/*.txt
  • The command is the program to run: grep, ls, uv, git.
  • Options (flags) change how it behaves. Short ones start with one dash and can be combined (-il is -i -l); long ones start with two dashes (--version, --help).
  • Arguments are what it acts on: a search word, a file, a folder.

When you meet a new command, most will explain themselves: try grep --help, or man grep on macOS and Linux (press q to quit the manual), or Get-Help Select-String in PowerShell.

Moving around and handling files

Here is the core set of commands, built up as a real session. Open a terminal and type along. Each block shows the command, then what you should see.

Where am I, and what is here?

pwd
ls
/Users/arjun
Desktop    Documents    Downloads    code

pwd prints the working directory. ls lists what is in it. (ls -a also shows hidden files whose names start with a dot, like .env; in PowerShell use ls -Force.)

Move, and make a practice folder.

cd code
mkdir terminal-practice
cd terminal-practice
pwd
/Users/arjun/code/terminal-practice

cd changes directory; mkdir makes one. Two special names help you move: .. means “the folder above this one”, and ~ means your home folder. So cd .. goes up one level and cd ~ goes home from anywhere.

Create, read, copy, rename and delete files.

echo "Refund requested for order CR-20931" > note.txt
cat note.txt
cp note.txt note-backup.txt
mv note-backup.txt old-note.txt
ls
rm old-note.txt
ls
Refund requested for order CR-20931
note.txt    old-note.txt
note.txt

echo prints text, and > redirects that output into a file instead of the screen, creating or overwriting it (>> appends instead). cat shows a file. cp copies, mv moves or renames, and rm removes. These all work in PowerShell too, which has built-in aliases with the same names.

Paths: absolute and relative. A path is the address of a file or folder. An absolute path starts from the very top of the drive and works from anywhere: /Users/arjun/code/terminal-practice/note.txt on macOS, /home/arjun/... on Linux, C:\Users\arjun\... on Windows. A relative path starts from where you are standing: note.txt, or ../crumb-lab/main.py (“up one, then into crumb-lab”). Relative paths are shorter; absolute paths are unambiguous.

Two habits that save hours. Press Tab while typing a file or folder name and the shell completes it for you (press it twice to see options). It also prevents typos: if Tab will not complete it, it does not exist where you think. And press the up arrow to bring back your previous commands instead of retyping them.

Stopping things. If a command is running and will not stop, press Ctrl+C. This is how you will stop servers, runaway scripts and anything that seems stuck. (In a terminal, Ctrl+C means “stop”, not “copy”.)

Environment variables and PATH

Remember the setup lab, when uv was “not found” until Arjun opened a new terminal? Here is why.

When you type uv, the shell has to find a program by that name. It looks through a list of folders stored in a variable called PATH, in order, and runs the first match. A new program installed in a new folder is invisible until that folder is on the list, and a terminal reads the list when it starts. Hence: install, then open a new terminal.

PATH is one of many environment variables: named values that every program started from your shell can read. You can see and set them:

echo $HOME
export CRUMB_STORE=baner
echo $CRUMB_STORE
which uv
/Users/arjun
baner
/Users/arjun/.local/bin/uv

export sets a variable for this terminal session and every program started from it. which shows exactly which program the shell would run. The PowerShell versions are $env:HOME, $env:CRUMB_STORE = "baner" and Get-Command uv.

Environment variables matter enormously in AI work, because this is how API keys reach your code. anthropic.Anthropic() reads the ANTHROPIC_API_KEY environment variable. Your .env file, loaded by python-dotenv, is a convenient way to set such variables for one project without typing export every time. And a variable set with export disappears when you close the terminal, unless you add it to your shell’s startup file, which is how Arjun ended up with an old key overriding his .env in the setup lab.

Note

Pause and think. Arjun types export ANTHROPIC_API_KEY=sk-ant-new... in one terminal window, then runs his script in a different window and gets an authentication error. Why?

Show the answer

An exported variable only exists in the shell where it was set, and in programs started from that shell. The second window is a separate shell that never saw the export. This is one reason .env files are popular: the script loads its own variables wherever it runs, instead of depending on which window you happened to type export in.

Where it breaks

The terminal is powerful precisely because it does exactly what you say, immediately, without asking “are you sure?”. That is also how it bites.

rm is forever. There is no Recycle Bin or Trash for rm. On Wednesday, Arjun wants to delete a folder called export along with its contents and types:

rm -r export *

He meant rm -r export/*. The stray space turns it into two arguments: export, and *, which the shell expands to every file in the current folder. His three test scripts vanished along with the export. They were recoverable only because he had saved them with git that morning, which is the next lesson. Habits that help: run ls with the same pattern first to see what it matches (ls export * would have shown him), use rm -ri to be asked about each file, and never type rm in a hurry.

Spaces in names. The shell splits arguments on spaces. cd Personal Project tries to go to a folder called Personal, with an extra argument Project. Wrap such paths in quotes, cd "Personal Project", or let Tab complete them, which adds the escaping for you.

Copy-pasting commands from the internet. A command is an instruction with your full permissions. Read before you run, especially anything containing sudo (run as administrator), rm -rf, or curl ... | sh (download a script and run it). Only run those from sources you trust, like official documentation.

Mac, Linux and Windows differ. Most everyday commands work everywhere, but not all. grep, wc and touch do not exist in plain PowerShell, and flags differ between macOS and Linux versions of the same tool. When a tutorial’s command fails, check which shell it was written for. Many Windows developers install WSL (Windows Subsystem for Linux) to get a real Linux shell; it is optional for this course, though Docker Desktop on Windows uses it behind the scenes, as you will see in a later lesson.

Try it yourself

In a new folder, recreate a mini version of Priya’s export and answer her question.

  1. Make a folder called inbox and move into it.
  2. Create three files: a.txt containing “Where is my hamper?”, b.txt containing “I want a REFUND”, c.txt containing “refund for the squashed cake please”.
  3. Count how many files mention “refund”, in any capitalisation.
  4. Bonus: list the matching lines themselves, with filenames.
Show the answer

macOS and Linux:

mkdir inbox
cd inbox
echo "Where is my hamper?" > a.txt
echo "I want a REFUND" > b.txt
echo "refund for the squashed cake please" > c.txt
grep -il refund *.txt | wc -l
grep -i refund *.txt

The count is 2. The bonus prints b.txt:I want a REFUND and c.txt:refund for the squashed cake please: without -l, grep shows each matching line, prefixed with its file.

PowerShell:

mkdir inbox
cd inbox
"Where is my hamper?" | Out-File a.txt
"I want a REFUND" | Out-File b.txt
"refund for the squashed cake please" | Out-File c.txt
(Select-String -Path *.txt -Pattern refund -List).Count
Select-String -Path *.txt -Pattern refund

Common mistakes

  • Running a command in the wrong folder. Before anything that changes files, run pwd. Most “file not found” errors are really “you are standing somewhere else”.
  • Typing the prompt. Tutorials often show $ ls. The $ is the prompt, not part of the command.
  • Forgetting to open a new terminal after installing a tool. The old window’s PATH does not know about it.
  • Using rm with wildcards without looking first. Run ls with the same pattern, read the list, then delete.
  • Pressing Ctrl+C to copy text. In a terminal it stops the running command. Copy with Cmd+C on macOS, or Ctrl+Shift+C in most Linux and Windows terminals.

Recap

  • The terminal is a window; the shell (zsh, bash, PowerShell) runs the commands you type in it.
  • Every command runs from a working directory; relative paths are relative to it. pwd, ls and cd tell you where you are and move you.
  • A command is command -options arguments, and small commands combine with pipes (|) and redirects (>).
  • Environment variables, including PATH and your API keys, are named values that programs started from the shell can read.
  • The terminal never asks “are you sure?”: look before you rm, quote paths with spaces, and read commands before pasting them.

At 10:58, Arjun walks into Meera’s meeting with a number. “84 of 412 emails mention a refund. About one in five.”

“How long did that take?” Meera asks.

“Half a second,” he says. “After forty minutes of doing it by hand.” Then, with a sheepish glance at Priya: “And on Wednesday I nearly deleted my own scripts with one stray space.”

“Nearly?” says Meera.

“I had saved them in git that morning.” Priya smiles. “Which is exactly what we learn next.”

Go deeper

Check your understanding

3 quick questions
1. `cat notes.txt` works in one terminal window and fails with "No such file or directory" in another, at the same moment. Most likely cause?
2. In `grep -il refund support-export/*.txt | wc -l`, what does the `|` do?
3. What did the stray space in `rm -r export *` do?