The terminal, and why it is not optional
The handful of commands that cover ninety per cent of a backend engineer's day, and why the GUI cannot replace them.
The terminal is a text conversation with your machine. You type an instruction, it answers. That is all it is, and the reason it will not go away is that text is the only interface that can be written down — scripted, logged, put in a pipeline, pasted into a ticket by somebody trying to help you.
A backend engineer lives here. Not because the GUI is bad, but because the servers your code runs on have no GUI at all.
The shape of a command
javac -d out Hello.java
───── ── ─── ──────────
│ │ │ │
│ │ │ └── argument: what to act on
│ │ └───────── the flag's value
│ └───────────── flag: changes how it behaves
└─────────────────── the program to runEverything follows that shape. Once you see it, an unfamiliar command stops being noise: you can tell which part is the program and which parts are instructions to it, even when you know nothing about the tool.
Two conventions worth knowing immediately: a single dash usually introduces a one-letter flag (-d), two dashes a word (--release), and almost every program answers --help.
The commands that cover most days
| Command | What it does | The one thing to remember |
|---|---|---|
pwd | print working directory | "where am I" — the answer to most confusion |
ls | list files | ls -la shows hidden files and details |
cd | change directory | cd .. goes up; cd alone goes home |
cat | print a file | fine for small files, terrible for large ones |
less | page through a file | q quits. Everybody forgets this once |
grep | find lines matching a pattern | grep -r "text" . searches a whole tree |
tail | the end of a file | tail -f app.log follows it live — the one you will use most |
mkdir | make a directory | -p makes parents too |
cp / mv / rm | copy, move, remove | rm does not ask, and there is no bin |
That last row deserves its own warning.
Piping: the idea that makes it powerful
Any program's output can become the next program's input, with |:
grep ERROR app.log | tail -20Find the lines with ERROR, then show me the last twenty of those. Neither program knows about the other. grep does one thing, tail does one thing, and the pipe composes them.
This is the whole philosophy, and it is why the tools are so small: you are not meant to find one program that does what you want. You are meant to join three.
grep ERROR app.log | grep -v Timeout | wc -lCount the error lines that are not timeouts. Three tools, one question answered, and you could keep going.
Watch it narrow
The argument for pipes is easier to believe with numbers on it. A log file with two hundred lines in it:
$ wc -l app.log
200
$ grep ERROR app.log | wc -l
90
$ grep ERROR app.log | grep -v Timeout | wc -l
35200 → 90 → 35. Each stage hands its output to the next as plain text, and nothing in the middle is written to disk or held anywhere you could look at. Then swap the counter for the thing you actually wanted:
$ grep ERROR app.log | grep -v Timeout | tail -3
2026-09-12T10:15:00Z ERROR NullPointerException in OrderMapper
2026-09-12T10:17:00Z ERROR NullPointerException in OrderMapper
2026-09-12T10:18:00Z ERROR NullPointerException in OrderMapperTwo hundred lines to the three that matter, with no program written and nothing installed. Notice what happened at the second stage in particular: grep -v Timeout threw away fifty-five error lines as noise you already know about, which is the move that turns an unreadable log into a readable one.
Where you will actually use it
Not for writing code — you have an IDE for that. For everything around it:
- Reading a log on a server that has nothing else
tail -fwhile you reproduce a bug- Running the build, the tests, the container
- Git
- Finding which of 4,000 files mentions a class name
- Being inside a container, where there is nothing but a shell
Try it yourself
Ten minutes that pay for themselves
In a terminal, without looking anything up beyond --help:
- Find out where you are, then list everything including hidden files.
- Make a directory, move into it, create a file with some text in it, and print it.
- Search your whole home directory for files whose name contains "java" — and notice how long it takes and how much it prints.
- Run
ls --help(orman ls) and find the flag that sorts by modification time.
The commands
pwd
ls -la
mkdir scratch && cd scratch
echo "hello" > note.txt
cat note.txt
find ~ -iname "*java*"
ls --help | grep -i "sort" # -t sorts by timeStep 3 is the instructive one: it prints more than you expected, and it is slow. That is what teaches you to narrow a search before running it — a habit that matters far more on a server with a million files than on your laptop.
Misconceptions
- "The terminal is for experts." It is for anybody who wants to repeat what they did. A click cannot be pasted into a runbook.
- "I'll learn it when I need it." You need it the first time production is broken, which is the worst moment to be learning
tail. - "Memorising commands is the skill." The skill is knowing a tool exists and that
--helpwill tell you the rest. Nobody rememberstar's flags.