20

Somewhere I saw a rant against java/javac allegedly using a mix of Windows and Unix style like

java -classpath ... -ea ... Something

IMHO, it is no mix, it's just like find works as well, isn't it? AFAIK, according to POSIX, the syntax should be like

java --classpath ... --ea ... Something

and -abcdef would mean specifying 6 short options at once. I wonder which version leads in general to less typing and less errors.

I'm writing a small utility in Java and in no case I'm going to use Windows style /a /b since I'm interested primarily in Unix. What style should I choose?

maaartinus
  • 2,633
  • 1
  • 21
  • 29
  • 1
    POSIX 1003.1-2003, Base Definitions, Chapter 12, Section 2 gives the following guidelines about utility command-line syntax: "Each option name should be a single alphanumeric character (the alnum character classification) from the portable character set." and "All options should be preceded by the ’−’ delimiter character." – Greg A. Woods Nov 18 '12 at 04:05

4 Answers4

28

You can find the POSIX argument conventions in the Utility Conventions chapter. The POSIX style consists of options with a single dash followed by a single letter indicating the option, with the argument value separated from the option by a space.

There are exceptions to the rules - find, for example - but these are because of the historical Unix precedents.

The X Windows (X11) uses find-like single-dash, long name options.

The double-dash long name options were pioneered by GNU (after a detour using + as a prefix).

See this StackOverflow question for a discussion of the wide variety of known command line argument handling systems - there are lots. (Since this was written, the powers-that-be decided the question SO 367309 was not a good fit for SO. I've transferred the answer to another question, What is the general syntax of a Unix shell command?.)

You could extend the list of techniques to cover git (and a number of other systems) where you get a structure like:

  • basecommand [global options] subcommand [sub-command options] [name ...]

There may be many sub-commands, each with its own lexicon of options.

Of course, Windows uses (used) slash '/' to indicate options instead of dash '-'.

JCL (for z/OS, and OS/360, and intermediate systems) tends to use positional parameters separated by commas, and is generally regarded as not being user-friendly or a good interface.

Jonathan Leffler
  • 1,846
  • 14
  • 21
  • 1
    +1 For the nice links and mentioning `git`. – maaartinus Apr 22 '11 at 22:51
  • I like all the answers, accepted this one because of the links. – maaartinus Apr 26 '11 at 21:53
  • The stackoverflow question seems to have been deleted (or possibly moved)... anyone know where it went? I'm curious to read it. – mizipzor Nov 20 '12 at 16:11
  • 1
    @mizipzor: See update for current location of the information. See also [Short/long options with option argument — is this some sort of convention?](http://stackoverflow.com/questions/10818443/short-long-options-with-option-argument-is-this-some-sort-of-convention/10818697#10818697) – Jonathan Leffler Nov 20 '12 at 17:01
  • "Of course, Windows uses (used) slash '/' to indicate options instead of dash '-'." The majority of Windows command line tools now support both, and PowerShell is going the way of using dash only. – jpmc26 Jul 11 '16 at 15:50
  • The only POSIX compliant way of giving command options with names longer than a single character is the "-W option=value" syntax. It has fallen into disuse recently, but the rationale is the same as with java's -D and -X options – Mirko Klemm Jan 15 '19 at 12:50
19

EDIT: It's been pointed out that this style is a GNU-ism, and that non-GNU based Unixes tend to use a single-dash syntax (in particular, OS X and BSD variants).

Despite it's GNU-ism status, many newly written Unix-style programs use this style:

  • --long-option for long option names,
  • -s for short (one-character) options,
  • -abc for multiple short options without arguments (one character per option).
  • Options with arguments:
    • --long arg or --long=arg for long options,
    • -s arg, -sarg or (optionally) -s=arg for short options. This can be combined with other short options, as long as only the last one has an argument.
  • The same "semantic" option can have several aliases, most commonly a short (quicker to type) one and a long (easier to remember) one.

Anybody that has used a Linux shell for any amount of time should be familiar with this style1, so it has the principle of least surprise on its side. Allowing grouping of multiple short options without being ambiguous with long options is also nice.

1For example, some of the programs using this style (on my Linux machine): ls, grep, man, sed, bash, etc. (EDIT: these are apparently GNU-isms though, BSD and OS X machines don't use this style)

There are several libraries that can take care of parsing this for you (the most well-known being GNU's implementation of getopt), only needing you to specify what long and short options exist, whether they take an argument, and what to do when an option is found. (And of course, what to do for positional arguments, i.e. ones that don't start with - and are not arguments to previous options)

find is a very old program (or maybe more likely: a rewritten version of a very old program) that can't easily be changed to use a new command line syntax. Too many scripts would break, and too many users used to the old syntax would complain. javac was likely influenced by gcc and friends, which likewise follow an old syntax for historical reasons.

Frits
  • 769
  • 4
  • 11
  • +1 - Additionally, when you have hundreds of options, you just _have_ to get creative (e.g when writing a compiler) – Tim Post Apr 21 '11 at 22:38
  • 2
    You give the impression that all Unices uses GNU utils (ie dash-dash args) and that is wrong. Mac OS X has no support for them, and the same applies for Free BSD. – Martin Wickman Apr 23 '11 at 08:44
8
  • Argument with dash-dash (--long-arg) is a GNU convention (see their getopt implementation).
  • POSIX commands never uses double dash arguments. This applies to most variants of Unix (Mac OS X, BSD) except Linux which uses GNU by default.

For your Java project, you might want to check out GNU getopt for Java or Apache CLI. They support both conventions.

A third option is to use Java VM arguments and let the runtime parse them for you:

 $ java -Dcolor=blue

And then, in code:

 System.getProperty("color");

Personally, I'd use the -D idiom and wrap the Java incantation in a shell-script which handles the command line parsing including checking classpath etc. This also makes it easier for native users to run your Java program.

Martin Wickman
  • 13,305
  • 3
  • 31
  • 66
1

It depends. I personally prefer the POSIX style, but in your case I would probably aim for consistency with the environment in which your tool is going to be used. This means using the Java convention for JARs (unless you plan to have a wrapper script that would make it look like a typical Unix command).

Adam Byrtek
  • 1,104
  • 7
  • 10