Purveyor of Single Sign-on SSH | The better way to manage SSH credentials

The Poetics of CLI Command Names

Carl-Tashian.jpg

Carl Tashian

Follow Smallstep

"And the words slide into the slots ordained by syntax, and glitter as with atmospheric dust with those impurities which we call meaning."
— Anthony Burgess, Enderby, 406

Naming a CLI command requires deep and careful deliberation. Yet most commands seem to have been named with playful insouciance at best, and foolish indifference at worst—with neither the forethought required to stand the test of time, nor the respect demanded of the long and venerable history of the command line. If naming things is one of the two most important and challenging tasks we face as programmers, why do many commands seem to have been named so arbitrarily?

A terrible command name is a curse, but a great command name has a poetic elegance. If you're adding something to the command line spell book, I hope this post can help bring clarity and consideration to the process.

Command naming anti-patterns

Because the first step is to avoid catastrophe.

  • The following words should never be in any command name: tool, kit, util, easy.

  • There's no excuse for requiring the user engage the shift key. I'm looking at you, VirtualBox and easy_install.

  • If you spend enough time thinking about command names, you will discover with delight that it is technically possible to name your command 🐥_Tool. Please don't.

  • How does it feel to type the command? Is it awkward or satisfying? How much finger travel is required? For example, sha256sum feels like gargling sand, but Wireshark's capinfos command is a soft breeze across the keys.

  • The version number should never appear in the command name. It's 2020, and there is a command on my system called python3.7m. Nothing reveals the erosion of our ancient and beloved command line ecosystem more clearly than this. In 50+ years of typing into terminals, we have not figured out how to have multiple versions of things coexist peacefully.

  • Don't start your command name with the letter g even though it's a perfectly fine letter situated right in the center of the keyboard. All past and future g commands are the personal property of Richard Stallman, who in 1983 was granted an exclusive, perpetual, irrevocable, worldwide license to the entire g namespace. Although he grudgingly granted exceptions for git and go, if you're not Linus Torvalds or Google, don't bother hitting him up.

  • The previous bullet point was a joke.

  • The more niche your command, the longer its name should be. Very short names should be reserved for utilities people use all the time, like cd, ls, rg.

  • Unless your package consists of a suite of shell utilities, don't pollute the namespace with dozens of commands. Install one or two commands, and use subcommands to reach different corners of your program. Of course, there are many reasons you may want the crisp boundaries afforded by separate executables. If you really need more than a few binaries, you can always make them callable from one or two central commands. Git does a great job here; you can extend Git by putting an executable in your $PATH called git-[command], and you'll be able to reach it using git [command].

  • Don't name your command after a new standard or a protocol or file format. These things go in and out of fashion, and they're often too specific. If you would like your command to find its way into the Golden Spellbook of Timeless Unix Commands, don't call it openssl. Surely whoever named openssl is regretting it to this day. Will they ever rename it to opentls? No way. It's too late. It's in too many Bash scripts now. We have to live with openssl until the sun swallows us up. Same deal with ffmpeg, which does far more than fast forward MPEG files.

  • Don't name your command after the kind of user interface it provides. Example: cfdisk is a version of a prior command (fdisk) with a newer interface (Curses). This is a case where the developers spent so much time working on the Curses interface that they decided to celebrate their achievement in the name of the command itself. But from a user's perspective, it really doesn't matter. It's moot. Imagine if Slack called itself webirc.

  • Don't make broad claims on generic words. For years, ImageMagick provided the convert command. Unless you have built a tool that is able to convert anything to anything—a Markdown file to a jpg, a salad spinner to a garlic press—you should not name your program convert.

    ImageMagick version 7 wisely gave up their claim on convert in favor of the new magick command, which has a convert subcommand. They were forced to give up convert because Windows also has a convert command. Do you know what the Windows convert command does? I'm sure you don't. And you're a pretty smart person. convert in Windows is used to convert a disk between different types of filesystems. 😒 What a perfect example of a command that claims a name way too broad for an incredibly small niche!

  • Don't depend on your command's name to determine its scope. Keep those decisions separate.

  • Imagination will get you far. You might get inspired with a favorite book of Filipino folk tales, some Norse mythology, Shakespearean sonnets. Just don't get too into the Norse mythology, okay? Maybe the story of Yggdrasil gave you a deep sense of clarity in your life path. I don't know, I haven't read it. But I don't need to read it to tell you that it's a diabolical name for a shell command.

Excellent names

vim is a brilliant name because vim is exactly what you feel after pulling off a ninja substitution that turns your CSV into JSON, or a crafty multi-line edit that sorts a list of horror movie titles by descending Rotten Tomatoes score. vim is the "improved"—now standard—version of vi. I'm still not sure why the people of ancient Rome who invented vi decided to name their text editor after the number 6?

curl might be the most cleverly named command of all time. It's a verb. It brings to mind a beckoning finger. It does what it says it does, and when you spell it out loud it sounds like "see URL."

  • Not all of the best 2-5 letter words have been used up. Please don't make me tab complete the name of your command.

  • Consider how your command will be pronounced around the world. Kodak is a word that was designed to sound the same in many languages. lego and ikea might be great command names too, if they weren't already trademarked.

  • Can you type your command with one hand—like cat—while your other hand is on the mouse?

  • Would your command read well in a poem?

    Ah, bitter chill it was!
    The owl, for all his awk, was a-cold;
    The gunicorn limp'd trembling through the frozen grass,
    And silent was the yacc in woolly fold
    —Paraphrased from John Keats, The Eve of St. Agnes

    Hey it's just a rule of thumb, but notice how the command AssetCacheTetheratorUtil (added to macOS in 2017) would never fly here.

  • If you really want to be both literal and niche, you could signal the solution domain in your name for clarity. But you're walking a fine line here. The ancient mkfs tries. It nestles well into the group of commands related to making things in the filesystem, like mkdir , mknod, mkfile, mktemp, and even mklost+found. It might be a bit of an overreach to use mk as the commonality here, given that one could imagine lots of commands for making things not related to the filesystem. But, files are a primary abstraction provided by the operating system, so it's not the worst thing to use mk for.

  • Thoughtful meaninglessness is completely fine and might even be your best option if you expect your command's solution domain to evolve. I still don't know what an emac is or why I need several of them to edit a file. Meaninglessness is the route we took here at smallstep, where we have humbly laid claim to the step and step-ca commands for our public key encryption toolkit and certificate authority. The naming of step pays homage in a small way to the Moon landing, but as a name it really has no connection to crypto, and that's okay because it's easy to type!

  • None of the above matters if your command doesn't actually do something useful.

Have you had the task of naming a CLI command? What was your approach? Hit us up on Twitter.

Carl Tashian (Website, LinkedIn) is an engineer, writer, exec coach, and startup all-rounder. He's currently an Offroad Engineer at Smallstep. He co-founded and built the engineering team at Trove, and he wrote the code that opens your Zipcar. He lives in San Francisco with his wife Siobhan and he loves to play the modular synthesizer 🎛️🎚️

certificate-manager-icon-blue.svg

Experience SSH certificates for yourself in <5min⚡!