Why I love using command line interface?
My Saturday started by waking up to a Twitter thread I was tagged into:
Why do you love (or do you?) the old school command line interface? What are the best use cases for it in API related work? @janik6n @Hamatti @anttiviljami @SvenWal @agraebe
Asking some opinions and might take some to future posts in #100DaysDX #Devrel #developer #CLI— ᴊᴀʀᴋᴋᴏ #dxdoctor ᴍᴏɪʟᴀɴᴇɴ (@Jarkko_Moilanen) July 27, 2019
Tweeting out my answers, I started to come up with more and more reasons, so I figured I'll also document them down here in my blog and open up each point a little bit in detail.
1) You can replicate commands
The first benefit that came to my mind when I started thinking about this, was replicating commands. If I use a GUI, to replicate some complex action, I need to do a lot of clicking around, whereas using command line, I can run the command with one copy-paste command (or using history feature) as many times as I want without having to do any more work.
Replicating commands provides a way to upfront the amount of work that needs to be done. Sometimes it's bit more but quite often, if you run the command more than once, you start winning time and effort.
Replication has other benefits too. Let's say I want to download 100 Youtube videos:
Using a GUI
With a GUI (of an imaginary downloader software), I have to copy-paste the urls one at the time, click Download, wait and repeat.
Oh wait, what if I realize that the application downloaded all videos with default 240p quality? Maybe I go to settings, change a quality setting to 1080p and start pasting in those URLs again.
Using a CLI
With a CLI, I can dump all 100 URLs to a file and run a download command for each line in that file. With one command, I just downloaded 100 files.
And if I need to change the quality option, I can just add an option flag to my loop, rerun that one command and wait as my videos are downloaded.
2) History
Second one of my favorite aspects about command line interfaces is that I get access to history of commands. I can easily repeat the previous command or search for any command I have run before.
With most GUI applications, I have used, this is not possible. Some photo or video editing software has repeatable history but most software doesn't.
I personally use mcfly as my bash history search app. With it, I can quickly find and re-run commands that I have done before.
3) Chain commands
If a CLI application is designed nicely, it takes input from stdin and outputs to stdout. Of course not all CLI apps do this and for some apps it doesn't even make sense really.
But many do. And that design allows for chaining commands. You can take your toolbox of bash tools for example and mix-and-match them however you want.
For example, let's say we are interested in Pokemon TCG cards (if you've been reading my blog, it should be quite obvious I'm a huge Pokemon fan). We want to know every unique card name that includes 'Charizard':
curl https://api.pokemontcg.io/v1/cards?name=Charizard | jq '.cards | .[] | .name' | sort | uniq
Here we curl'd an API, which returns a JSON into the stdout. We then pass that JSON to jq, that reads JSON from stdin and allows us to do operations on it. In this case, we access the cards
property and get all the name
properties. Once again, we output that to stdout so that sort
can read it, sort alphabetically and finally uniq
removes duplicates.
Some GUI software aimed for interacting with HTTP calls allows this kind of operation built-in. But the beautiful thing with the command line is that we can combine any tools we want. You don't have to plan for every possible use case when building the tool: as long as you read from stdin and print to stdout, your CLI app can be combined with any other.
4) Programmability
An extension of the replicability in #1 is that we can alter conditions and parameters of calls programmatically. Let's expand on the downloading Youtube video examples from #1.
Maybe this time we get a mix of different sources, not just Youtube. You can use basic conditionals within your script to call different applications based on the source or filetype.
Maybe you pass Youtube links to Youtube downloader, image and txt file links to curl or wget and some other proprietary formats to specific software that allows extracting the information.
5) Share commands
How many times have you helped someone remotely to use their computer for something? Maybe it's a friend who needs to install some software or maybe it's a colleague trying to setup their development environment. Or maybe you're writing a blog post teaching people how to use a software.
With GUI apps, it's often bit vague "click on the blue button in the upper right corner that says Scan" verbal instructions or screenshots/screencasts. The instructions grow quite long and take a disproportional amount of time to write down.
With CLI apps, you can just copy-paste the commands and send them to the one in need or add them to your blog. Please be careful though: running commands that someone else tells you to run is very dangerous. You should never blindly run commands anyone tells you to run without understanding what they do. I have seen some havoc that has been done to systems by misinformed users.
6) Automation / scheduling with cron
The universality of these command line tools means that you don't have to build every feature to every application. If we continue with our example of downloading Youtube videos:
You know that your favorite creator uploads a new video every Monday at 10.00. You could set yourself a reminder to download it with your GUI app manually or hope to find a GUI app that downloads Youtube videos and allows scheduling.
Or you can use the CLI downloader and combine that with cron. Now you can use one app to find the URL to the latest video, feed that to the downloader and schedule it all to happen every Monday at 10.05.
Cron is great for maintenance tasks that are essentially the same task run over and over again on regular intervals. Like doing backups, cleaning up some upload folders, etc.
7) Less change in interface
I left this one for last because it's a bit different and less universally true. I have noticed that GUI applications quite more often make changes to their UIs than CLI applications to their API. That makes using history and written-down instructions much better at lasting time.