Lesson 01 · Bash · Mission strand: read & debug others' scripts
Before you can write bash, you need to stop seeing commands as magic strings. Every command has the same three-part shape. Learn to see it once and it never goes away.
You have been copying commands other people gave you. The problem with that isn't that it doesn't work — it usually does. The problem is you can't tell a harmless command from one that deletes your afternoon, and you can't fix one when it breaks.
This lesson gives you one thing: the ability to look at an unfamiliar command and name what each piece is doing. That's the foundation the other two mission strands sit on.
This is worth clearing up immediately, because it silently confuses people for months.
Open your terminal and type this, then press Enter:
echo $0
-zsh
On your Mac that prints zsh, not bash. Since 2019, macOS ships zsh as the default shell.¹ A shell is just the program that reads what you type and runs it.
zsh and bash are close cousins — nearly everything in this lesson is identical in both. Where they genuinely differ, the lesson will say so. To step into real bash deliberately, type bash; to leave it, type exit.
The bash on your Mac is version 3.2.57, released in 2007. Apple froze it over a software licence disagreement. Modern Linux servers — the ones your mission ends on — run bash 5. So a handful of newer bash features will fail on your laptop but work on your server. I'll flag those when we reach them; you don't need to do anything about it today.
Essentially every command you will ever read has this structure:
Read it as a sentence: list (command), in long form (option), the thing called logs (argument).
The shell splits your line on spaces. The first word is the command; everything after is handed to it. That single rule explains an enormous amount of bash behaviour later — including why filenames with spaces cause so much grief.
A short option is one dash and one letter: -l. A long option is two dashes and a word: --help. Short options can usually be bundled — ls -la means -l and -a together.
Your instinct will be to type ls --help. On your Mac that fails: ls: unrecognized option `--help'.
macOS inherits its core tools from BSD Unix, and many BSD tools have no --help at all. Linux uses the GNU versions, which do. This is the most common reason a command copied off the internet works for someone else and not for you. When --help fails, reach for man instead.
Nobody memorises these. What separates someone fluent from someone stuck is knowing the two lookup moves.
1. man — the manual, built into your machine, works offline:
man ls
Press Space to page down, type / then a word to search, and press q to quit. That q matters — being stuck in man with no idea how to escape is a genuinely common first-week experience.
2. explainshell.com — paste any command and it labels every piece for you. This is the single best tool for your "read other people's scripts" goal. Use it on the next scary curl ... | bash line you're asked to run.
One more piece and you can decode a real command. When you write ls logs, where does it look for logs?
The shell always has a current directory — where you are standing. pwd ("print working directory") tells you:
pwd
/Users/alikibao/Desktop/Github/lessons/bash/practice
A path with no leading slash — logs, logs/app.log — is relative: it starts from where you're standing. A path beginning with / is absolute: it starts from the top of the disk and means the same thing no matter where you are.
Absolute paths are what you'll see in deploy scripts (/var/www/html), because a script can't assume where it's being run from. That's your first glimpse of why scripts look the way they do.
I've made you a sandbox at ./practice — a fake app with a build folder and a log file. Nothing in it matters, so break it freely.
Open your terminal and work through these. Predict the output before pressing Enter each time — the prediction is what makes it stick.
cd ~/Desktop/Github/lessons/bash/practice
pwd
cd means "change directory". ~ is shorthand for your home folder.
ls against ls -l. Name the three parts of the second one out loud.
ls
ls -l
ls -l logs
ls --help
Then get what you actually wanted: man ls — and press q to escape.
grep -c ERROR logs/app.log
Then run it. If you can explain why it printed what it printed, you've got this lesson.
Answer from memory — don't scroll up. Getting one wrong here is more useful than getting it right by peeking.
In grep -c ERROR logs/app.log, what is -c?
A leading dash marks an option. -c tells grep to count matching lines instead of printing them — which is why you saw 2 rather than two lines of text.
On your Mac, running ls --help does what?
macOS ships BSD tools, which largely lack --help. Use man ls. Remember this when a command works for a colleague on Linux but not for you.
You're in /Users/you/practice. Where does ls logs look for logs?
No leading slash means a relative path: it resolves from your current directory. So this looks for /Users/you/practice/logs.
The Linux Command Line, William Shotts — free PDF, and the standard recommendation for starting from zero. Read Chapter 1 (What Is the Shell?) and Chapter 5 (Working With Commands); together they're about twenty pages and cover this lesson in more depth.
If you'd rather read a wiki than a book, BashGuide — Commands and Arguments is the same ground from the people who maintain the definitive bash FAQ. Either is fine; don't do both.
Keep explainshell.com open in a tab as you go. And a warning that will save you real time: the top Google results for bash questions include two long-dead sources — bash-hackers.org (offline since 2023) and TLDP's "Advanced Bash-Scripting Guide" (teaches patterns now considered wrong). Both look authoritative. Prefer the links in RESOURCES.md.
I'm your teacher here, not just the author of this page. If any of this was unclear, or a command did something you didn't expect, or you want to know why something is the way it is — ask me. "Why does the shell split on spaces?" and "what actually happens when I press Enter?" are both excellent questions with real answers.
Next lesson: pipes and redirection — how | and > chain small commands into useful ones. That's the move that turns the log file in your sandbox into an answer, and it's the single most common construct in the scripts you want to read.
¹ Apple switched the default from bash to zsh in macOS Catalina (2019). Your /bin/bash is 3.2.57 — verified on your machine, not assumed.