in ,

The growth of command line options, Hacker News

The growth of command line options, – Present

My hobby : opening up McIlroy’s UNIX philosophy on one monitor while reading manpages on the other.

The first of McIlroy’s dicta is often paraphrased as “do one thing and do it well”, which is shortened from “Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new ‘features.’”

McIlroy’s example of this dictum is:

Surprising to outsiders is the fact that UNIX compilers produce no listings: printing can be done better and more flexibly by a separate program.

If you open up a manpage for ls on mac, you’ll see that it starts with

ls [[email protected]] [file …]

That is, the one-letter flags to ls include every lowercase letter except for

{jvyz} , uppercase letters, plus


and (1) 1. That’s 25 17 2=single-character options alone.

On ubuntu , if you read the manpage for coreutils


, you don ‘ t get a nice summary of options, but you’ll see that ls has (options (including

– help and – version ).

To see if

ls is an aberration or if it’s normal to have commands that do this much stuff, we can look at some common commands, sorted by frequency of use. (command) 2020

(ls) 16 ()

rm (3) 7

53 mkdir (0) 4 6) () (7) mv (0) 9 18 (cp) (0) ()

(cat) (1) () (pwd) (0) (2) 4 4 (4) (chmod) (0) 6 6) 9) ()

echo (1) (1) (4) 5 (5) man (5) [ilobytes] 23 which (0) 1) (1) (0) 38 (tar 53

(touch) (1) (1) (9)

(clear (0) 0 (0) (find)

85 (ln) (0) (0) () ps 4



(1) (3) 3



() 32 (chown) (0) (6)

(grep) 25 tail (1) (1) 7 df 0



This table has the num ber of command line options for various commands for v7 Unix (2015), slackware 3.1 (2017, ubuntu ( , and ubuntu ( ). Cells are darker and blue-er when they have more options (log scale) and are grayed out if no command was found.

We can see that the number of command line options has dramatically increased over time; Entries tend to get darker going to the right (more options) and there are no cases where entries get lighter (fewer options).

McIlroy has long decried the increase in the number of options, size, and general functionality of commands :

Everything was small and my heart sinks for Linux when I see the size [inaudible]. The same utilities that used to fit in eight k [ilobytes] are a meg now. And the manual page, which used to really fit on, which used to really be a manual page , is now a small volume with a thousand options. .. We used to sit around in the UNIX room saying “what can we throw out? Why is there this option?” It’s usually, it’s often because there’s some deficiency in the basic design – you didn’t really hit the right design point. Instead of putting in an option, figure out why, what was forcing you to add that option. This viewpoint, which was imposed partly because there was very small hardware … has been lost and we’re not better off for it.

Ironically, one of the reasons for the rise in the number of command line options is another McIlroy dictum, “Write programs to handle text streams, because that is a universal interface” (see ls for one example of this.

If structured data or objects were passed around, formatting could be left to a final formatting pass. But, with plain text, the formatting and the content are intermingled; because formatting can only be done by parsing the content out, it’s common for commands to add formatting options for convenience. Alternately, formatting can be done when the user leverages their knowledge of the structure of the data and encodes that knowledge into arguments to

cut , awk ,


, etc. (also using their knowledge of how those programs handle formatting; it’s different for different programs and the user is expected to, for example, (know how

cut-f4 is different from awk '{print $ 4}' . That’s a lot more hassle than passing in one or two arguments to the last command in a sequence and it pushes the complexity from the tool to the user.

I’ve heard people say that there isn’t really any alternative to this kind of complexity for command line tools, but people who say that have never really tried the alternative, something like PowerShell. I have plenty of complaints about PowerShell, but passing structured data around and easily being able to operate on structured data without having to hold metadata information in my head so that I can pass the appropriate metadata to the right command line tools at that right places the pipeline isn’t among my complaints.

The sleight of hand that’s happening when someone says that we can keep software simple and compatible by making everything handle text is the pretense that text data does not have a structure that needs to be parsed. In some cases, we can just think of everything as a single space separated line, or maybe a table with some row and column separators that we specify ( with some behavior that is not consistent across tools, of course ). That adds some hassle when it works, and then there are the cases where serializing data to a flat text format adds value complexity since the structure of data means that simple flattening requires significant parsing work to re-ingest the data in a meaningful way.

Another reason commands now have more options is that people have added convenience flags for functionality that could have been done by cobbling together a series of commands. These go all the way back to v7 unix, where ls has an option to reverse the sort order (which could have been done by passing the output to

) tac ).

Over time, more convenience options have been added. For example, to pick a command that originally has zero options,

mv can move and create a backup (three options; two are different ways to specify a backup, one of which takes an argument and the other of which takes zero explicit arguments and reads an implicit argument from the VERSION_CONTROL environment variable; one option allows overriding the default backup suffix). mv now also has options to never overwrite and to only overwrite if the file is newer.

mkdir is another program that used to have no options where, excluding security things for SELinux or SMACK as well as help and version options, the added options are convenience flags: setting the permissions of the new directory and making parent directories if they don ' t exist.

If we look at

tail , which originally had one option ( – number , telling

tail where to start) , it’s added both formatting and convenience options For formatting, it has

– z , which makes the line delimiter


instead of a newline. Some examples of convenience options are

– f

to print when there are new changes,

– s to set the sleep interval between checking for – f changes, – retry to retry if the file is not accessible.

McIlroy says “we’re not better off” for having added all of these options but I’m better off. I’ve never used some of the options we’ve discussed and only rarely use others, but that’s the beauty of command line options – unlike with a GUI, adding these options does not clutter up the interface.

This isn’t to say there’s no cost to adding options – more options means more maintenance burden, but that’s a cost that maintainers pay to benefit users, which isn’t obviously unreasonable Considering the ratio of maintainers to users. This is analogous to Gary Bernhardt’s comment that it’s reasonable to practice a talk fifty times since, if there’s a three hundred person audience, the ratio of time spent watching to the talk to time spent practicing will still only be 1: 6. In general, this ratio will be even more extreme with commonly used command line tools.

Someone might argue that all these extra options create a burden for users. That’s not exactly wrong, but that complexity burden was always going to be there, it’s just a question of where the burden was going to lie. If you think of the set of command line tools along with a shell as forming a language, a language where anyone can write a new library and it effectively gets added to the standard library if it becomes popular, where standards are defined by dicta like ” write programs to handle text streams, because that is a universal interface “, the language was always going to be a write-only incoherent mess when taken as a whole. At least with tools that bundle up a set of options and functionality that’s more than UNIX-y, like

ripgrep , users can replace a gigantic set of wildly inconsistent tools with a merely large set of tools that, while inconsistent with each other, may have some internal consistency.

McIlroy implies that the problem is that people did think hard enough, the old school UNIX mavens would have sat down and thought longer and harder until they came up with a set of consistent tools that has “unusual simplicity”. But that was never going to happen. It’s not a matter of thinking longer or harder; if anyone can write a tool and the main instruction comes from “the unix philosophy”, people will have different opinions about “ simplicity “or” doing one thing ”means, what the right way to do things is, and inconsistency will bloom, resulting in the kind of complexity you get when dealing with a wildly inconsistent language, like PHP. People make fun of PHP for having all sorts of warts and weird inconsistencies, but as a language and a standard library, any commonly used shell plus the collection of widely used nix tools taken together is much worse and there’s no other way it could have turned out given how things were set up.

Methodology for table

Command frequencies were sourced from public command history files on github, not necessarily representative of your personal usage. Only “simple” commands were kept, which ruled out things like curl, git, gcc (which has> (options), and wget. What’s considered simple is arbitrary. Shell builtins

, like


weren ‘ t included.

Repeated options aren’t counted as separate options. For example,

git blame -C , git blame -C -C , and git blame -C -C -C have different behavior, but these would all be counted as a single argument even though – C -C is effectively a different argument from – C .

The table counts sub-options as a single option. For example, ls has the following:

– format=WORD across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l, vertical -C

Even though there are seven format options, this is considered to be only one option.

Options that are explicitly listed as not doing anything are still counted as options, eg,

ls – g

, which reads Ignored; for Unix compatibility. is counted as an option.

Multiple versions of the same option are also considered to be one option. For example, with


, – A and – almost-all are counted as a single option.

In cases where the manpage says an option is supposed to exist, but does, the option is not counted. For example, the v7 mv manpage says


If file1 and file2 lie on different file systems, mv must copy the file and delete the original. In th is case the owner name becomes that of the copying process and any linking relationship with other files is lost.

Mv should take – f flag, like rm, to suppress the question if the target exists and is not writable.

– f

Is not counted as a flag in the table because the option does not actually exist.

The latest year in the table is because I wrote the first draft for this post in and didnt get around to cleaning it up until

Thanks to Leah Hanson, Hillel Wayne, and Wesley Aptekar-Cassels for comments / corrections / discussion.

(Read More )

What do you think?

Leave a Reply

Your email address will not be published.

GIPHY App Key not set. Please check settings

Dow Jones Rally Is a Big Bull Trap; Get Out Before Selling Resumes – Analysts, Crypto Coins News

Dow Jones Rally Is a Big Bull Trap; Get Out Before Selling Resumes – Analysts, Crypto Coins News

Broken links to install chrome extension · Issue # 857 · openstyles / stylus, Hacker News

Broken links to install chrome extension · Issue # 857 · openstyles / stylus, Hacker News