Why bother with the terminal
You can build a long career without ever opening a terminal. Plenty of people do. But at some point – usually when you're SSH'd into a server at 11pm or trying to script something a GUI will never do – the command line stops being optional.
That's the argument for learning it early instead of cornered into it. The terminal isn't a faster way to do what you already do with a mouse. It's the interface you'll meet the rest of the computing world through: servers, containers, CI runners, cloud instances, old Unix tools that still run the internet. Every one of them expects you to talk to it in text.
Most of what follows is the small amount of context and the small set of commands that I think are worth learning first, in roughly the order I'd introduce them to someone.
A quick word on terminology
People use "terminal" to mean three different things, which makes the whole topic more confusing than it needs to be.
Originally, a terminal was a piece of hardware. A screen and a keyboard wired into a mainframe somewhere else in the building, with no processing power of its own. When personal computers took over, we kept the text-based interface and moved it into software.
Today the pieces work like this:
- Terminal emulator. The app you open (iTerm2, Alacritty, Windows Terminal, Ghostty, the default Terminal on macOS). It draws the window and handles input.
- Shell. The program running inside that window (Bash, Zsh, Fish) that reads what you type, interprets it, and talks to the operating system.
You can mix and match. Your prompt customizations, aliases, and most of the "look and feel" you associate with the terminal actually live in the shell, not the emulator. This distinction matters the first time you want to move your setup to a new machine.
What you get out of it
A few things that GUIs can't really match:
The skill travels
VS Code's menus move around between versions. Windows Settings looks nothing like macOS System Settings. Meanwhile ls, cd, grep, and ssh have worked the same way for decades and run on everything from your laptop to a Raspberry Pi to an EC2 instance. Time spent learning them compounds in a way that time spent memorizing a particular UI does not.
Pipes change what's possible
The pipe operator (|) takes the output of one command and hands it to the next. That one idea is what turns a small set of commands into a general-purpose toolkit. For example, finding every text file that contains "error" and moving it into a debug folder:
grep -l "error" *.txt | xargs -I {} mv {} ./debug/
In a GUI that's a manual click-and-drag exercise. Here it's one line, and you can stick it in a script and forget about it.
Servers don't have monitors
If you end up anywhere near DevOps, backend, or cloud infrastructure, you'll spend real time in a shell. You can't RDP into a Lambda. You can't right-click a running container on a remote host. The terminal is where that work happens, and the sooner you're comfortable there, the less painful the first outage is.
You learn how the computer actually works
Using the terminal tends to push you into the model the OS is already using underneath. You stop guessing why a file won't save and start thinking about permissions (chmod, chown). You stop force-quitting from a menu and start thinking about processes and signals (ps, kill). You stop checking wifi bars and start reaching for ping, curl, and dig. None of this is strictly necessary to get work done – until it is.
How to actually get comfortable
The hardest part of learning the terminal is the first couple of weeks, when it's slower than what you already know. Some things that helped me:
Replace one workflow at a time
Pick something you do with a mouse and commit to doing it in the terminal for a week.
- Git. Close the Source Control tab.
git status,git add -p,git commit,git log --onelinewill cover most of what you need. - File navigation. Skip Finder/Explorer for anything inside a project.
cd,ls,tree. - Reading logs. Stop opening log files in a text editor.
tail -f,less,grep.
Full replacement isn't the goal. Just build the reflex to try the terminal first for one kind of task.
Don't try to memorize man pages
You don't need to learn every flag to every command. You need the daily drivers and the confidence to look up the rest when you need them. The core set is small.
Make the environment yours
The default terminal on most systems is ugly and unhelpful. A few changes make a real difference:
- A modern shell (Zsh with something like Oh My Zsh, or Fish).
- A prompt that tells you the current directory, git branch, and whether the last command failed.
- A readable monospace font (I like Geist Mono and JetBrains Mono).
- Two or three aliases for things you type all day – mine include
gsforgit statusand..forcd ...
You don't need a 400-line dotfiles repo. Start small and add things as they become obviously useful.
About platforms
Almost every server you'll ever touch runs Linux. SSH into an EC2 instance, a DigitalOcean droplet, a Pi, a friend's home server – you land in a shell.
The commands below work natively on Linux and macOS, which is Unix under the hood. On Windows, they work inside WSL or Git Bash. If you're on Windows and planning to do any backend or cloud work, get WSL installed before you go any further. The experience is dramatically better than PowerShell for this kind of work, and everything in the rest of this post will apply.
The cheat sheet
The commands that come up again and again, roughly grouped by what they do.
Navigation
| Command | Description | Example |
|---|---|---|
pwd | Print working directory | pwd |
ls | List directory contents | ls -l, ls -a |
cd | Change directory | cd ~, cd .. |
Files and directories
| Command | Description | Example |
|---|---|---|
mkdir | Make a directory | mkdir new_project |
touch | Create an empty file / update its timestamp | touch new_file.txt |
cp | Copy files or directories | cp file.txt backup/ |
mv | Move or rename files | mv old.txt new.txt |
rm | Remove files | rm file.txt, rm -rf dir (be careful) |
cat | Dump a file to stdout | cat log.txt |
less | Read a file interactively | less large_log.txt |
head | First N lines | head -n 10 file.txt |
tail | Last N lines, optionally following | tail -f log.txt |
Text and search
| Command | Description | Example |
|---|---|---|
grep | Search for patterns in files | grep "ERROR" app.log |
find | Search for files | find . -name "*.js" |
sort | Sort lines | `cat names.txt |
uniq | Collapse adjacent duplicate lines | `sort list.txt |
System and network
| Command | Description | Example |
|---|---|---|
ps | Snapshot of running processes | ps aux |
top | Live process monitor | top |
htop | Interactive process viewer | htop |
kill | Send a signal to a process | kill 12345 |
ping | Basic connectivity check | ping google.com |
curl | Make HTTP requests / download files | curl -O https://site.com/file.zip |
ssh | Secure shell to a remote host | ssh user@server.com |
Everything in that table is older than most of the software you use daily, and none of it is going anywhere. Start with the five or six commands you'd use today. The rest sticks as soon as you have a reason to reach for it.