My views on some conventions for Unix command line options
Recently I read Chris Wellons' Conventions for Command Line Options, which reviews these conventions. As it happens, I learned and have internalized a somewhat different version of how these conventions should be and how I expect programs to behave. I'm not going to mention things where my expectations agree with Wellons' presentation of the conventions, just where I differ.
On short options that accept an argument, Wellons says:
This technique is used to create another category, optional option arguments. The option’s argument can be optional [...]
There are no optional option arguments; an option either always
takes an argument or it never does. This is how the traditional
getopt(3) behaves, at least as far as I remember, and appears to
be how the 4.3 BSD
(It's also how POSIX
is required to behave; see the discussion of how
optarg is set.)
Options can typically appear in any order — something parsers often achieve via permutation — but non-options typically follow options.
Non-options always follow options. By extension, the first non-option
argument terminates scanning for options; any remaining '-...'
things become arguments. Again this is how the 4.3 BSD
is documented, and in fact that options and non-options can't be
intermixed is mostly required by the
getopt(3) returns non-option arguments to you is that it
gives you the index of the first argument in
argv. To support
intermixed options and non-options, it would have to permute the
order of entries in
argv to move all options up to before all
non-options. In modern C definitions of
getopt(3), including the
POSIX one, I
believe this is forbidden because
argv is declared
My strong cultural expectations for option handling only cover short options; while I have opinions about how long options should act, they're not as visceral as for short options. Just as with short options and for much the same pragmatic reasons, I don't believe in long options with optional option arguments; long options should either always take an argument or never do so. Behaving otherwise breaks my expectation that long options are just the same as short options except longer (and they can't be grouped, and there's that optional '=' thing for arguments).
(This difference between my views and Chris Wellons' views points out some general issues here, but that's for another entry.)