2020-08-09
Unix options conventions are just that, which makes them products of culture
Recently I wrote about my views on some conventions for Unix command line options, where I disagreed in part with what Chris Wellons considered Conventions for Command Line Options. Both Wellons and I have a lot of Unix experience, and that we disagreed on parts of what rightfully should be a well established core of Unix in practice shows some things about them.
The first thing to note about Unix's conventions on options is that
they've always been ad hoc and imperfectly adhered to, to the extent
that they even existed in the first place. To start with, V7 Unix
did not have getopt(3)
, so every V7 program did its own parsing
of options and I'm certain that some of them had somewhat different
behavior. Several V7 programs completely broke these conventions;
famously dd
doesn't even use conventional options that start with
a '-', and while find
has options that start with '-' they're
actually more like GNU style long options.
(Wikipedia implies that
getopt(3)
first appeared in System III, and indeed here's the
System III getopt(3)
manpage,
dating from 1980 (cf,
also).)
The second thing is that both Wellons and I can go on about conventions
all we want (and what they should be), but the reality is that the
'conventions' that exist are defined by what programs actually do.
If a lot of programs (or a popular option parsing library) behave
in a particular way, in practice that is the convention regardless
what I think of it (or write). The corollary
of this is that what people consider convention is in large part
defined by how the programs they use behave. By its mere existence
and popularity, GNU Getopt has defined a lot of the modern conventions
for options handling; if you deviate from it, you will surprise
people who expect your programs to behave like the other programs
they use every day. Before GNU Getopt was what most programs used,
getopt(3)
did the same thing and had the same effect for the
conventions it enforced.
(New options parsing libraries tend not to break too much with the current convention when they were initially written, but they can selectively change some of them, especially what are considered more obscure ones.)
Finally, I suspect that part of the difference between Wellons' view
of these conventions and mine is because of when we came into Unix. I
started using Unix long enough ago that it was in the era of classic
getopt(3)
instead of GNU Getopt (and long options), so the rules that
getopt(3)
enforced were the ones that I wound up internalizing as the
correct conventions. Someone who came into Unix later would have been
primarily exposed to GNU Getopt's somewhat different behavior, with it
supporting intermixed options and non option arguments, long options
being routine, and so on.
The corollary of this is that people who come into Unix today
are learning the conventions as they stand now, including any
inconsistencies between Unix programs that are increasingly written in
different languages, with different argument parsing libraries, and so
on. Some languages are sufficiently divergent that no one is going to
mistake them for 'how Unix commands should behave' (I'm looking at you,
Go), but others are close enough that people are likely to internalize
parts of their behavior, even if only as expected divergences and
differences, just as people remember find
and its unusual behavior.