There are many useful tools in Linux and macOS (… and *BSD and others) that can only be called from the command line. We’ve all called git
, cat
, curl
, less
, open
, grep
/rg
and others to do things that GUI programs can’t. Even if the GUI version can do it, chances are the command line version does it quicker. These can also be composed together to create simple new programs. For example, to solve a problem like
Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies
You could compose standard Unix tools like so:
This is Doug McIlroy’s solution to the problem. Maybe not the most efficient, but elegant, quick to write and easy to understand. Easy, if you already know what each command does.
These tools become obvious after you’ve spent time learning them, but they’re hard to decipher for someone who hasn’t. This is felt most acutely with tools like git
, which have several subcommands, with names that don’t always make sense and can easily be misused. I haven’t felt frustrated with git
in about 8 years, but it took me time to reach a point where I understood what it does and why.
How to learn
So how do we learn these tools?
1. help
Most of these tools come with a --help
or -h
switch, that tells you the options available, with a short explanation of what each does. It usually doesn’t tell you how to compose the various options. Trial and error is the way to go.
2. man
The man
or manual page is an exhaustive explanation of every possible thing you can do with this. man tar
on my machine is a 13 page whopper with the sections Description, Options, Environment, Exit Status, Examples, Compatibility, Security, See Also (similar/related commands), Standards, History, Bugs.
I’ve never read a man page from start to finish, and I’m not sure you’re meant to. While you can learn from the examples section, IMO, man pages are useful when you already have a good idea what the tool does and what it’s meant for, but want to investigate some less well-known option.
If you have a vague idea of what you want, you can search all local man pages with apropos [regex]
. If you’re interested in computing the checksum of a file, apropos checksum
returns several useful results.
3. Google/Stack Overflow
”How to X with Y tool” works great when you need to solve the problem right now and don’t have time to read long explanations. StackOverflow has our back when we’re in this situation. Here’s a couple from my search history
- How do I undo the most recent local commits in Git? [22500 upvotes]
- Permissions on private key in .ssh folder? [492 upvotes]
I need both of these threads about once a year. I can’t remember the exact answer from memory, and I don’t even try to. I can always look it up.
Generalising this approach, just keep googling for what you need to do, copy/pasting the commands. Necessity is a powerful motivator.
4. Articles/wiki on the internet
There are many helpful folks on the internet who write tutorials on how to solve certain problems or use specific tools. Recently I was setting up a VPN and found some well written articles.
My method - I read through and take notes. When I need to remember, I take a look at the notes. There’s a lot of spam out there, so I prefer to search on sites that I know have good content like Archwiki and DigitalOcean. The Wireguard wiki helped me learn what these config options meant and why we were setting them. Shorter articles or Q&As that merely gave me instructions weren’t enough to set up the network I wanted.
Articles also help when you don’t know what you don’t know. Like this list of Linux networking tools. If you knew nothing about network tools, not even names like nmap
and nc
, they give you a brief intro to get you started.
5. tldr
What usually works best for me is learning by example. If I see a few examples, I know how to use something. tldr
does exactly that.
I learned about netcat, netstat, nmap, tcpdump, ifconfig and others quicker with these cheatsheets than with other methods.
These cheatsheets have been translated into many languages. Anyone can contribute and improve them on github.
Go deeper
All of these resources tell you what the tools are and how to use them, but not why they were designed that way.
The Unix Programming Environment by Kernighan and Pike explains the philosophy behind these commands, like doing one thing well. It also gives a clear explanation of Unix concepts like pipes.
Commands that stick to the do-one-thing principle are easy to learn with the 5 methods I mentioned. With one exception. I think git
does enough things and has an awkward enough interface that it’s worthwhile to read Pro Git by Scott Chacon. Even skimming this book gives a good idea of all the things git
is capable of.
Conclusion
There’s no one-size fits all. People learn best when they use the method(s) that suits them. Find the combination that suits you and use that.
One last thing I didn’t mention earlier. More than efficiency, speed, composability or any of those minor concerns, we use the command line to look cool, like the Hollywood ideal of a hacker. In case anyone might walk by your screen, be sure to have cmatrix
running on a terminal.
Shoutout to asciinema
for creating these recordings. These files were an order of magnitude smaller than the equivalent gifs.
Thanks to Chandra Sekar for reading drafts of this and suggesting improvements.
Comments on Hacker News