Passing options to a program: what's the convention for one dash vs two?

Solution 1:

The most common is GNU getopt style, with one dash for short options and two dashes for long options.


  • Initially, Unix programs took single-letter options preceded by a single dash and optionally bundled:

    ls -laF
    
    ls -l -a -F
    

    The two commands above are equal.

    When an option takes a value, it overrides bundling: In gpg -aofoo.gpg, -a and -o are options and foo.gpg is the value given to -o.

  • Most of them did, anyway.

    tar cvzf is a common sight. Current versions accept tar -cvzf too, and depending on whether you add the dash the arguments will be interpreted in very different ways. For example, these two mean the same thing (note how dashless options are not immediately before their value):

    tar -xf file.tgz -vzO /etc/passwd /var/backups
    
    tar xfvzO file.tgz /etc/passwd /var/backups
    

    BSD ps always uses -; SysV ps never does. The Linux version accepts both versions and changes its behavior depending on whether an option was prefixed with a dash. (Unlike tar example above, ps changes the option meanings as well.)

  • X11 programs used long options preceded by a single dash or sometimes a plus sign:

    xterm -class FooTerm +vb -u8
    

    This sets options class and u8, and unsets the vb option.

    X11 style is incompatible with option bundling.

  • Later, long options were added to GNU getopt() in a way that's compatible with one-letter options.

    gpg -se --no-armor --output=signed.gpg
    

    This sets -s, -e, and --no-armor (which is opposite to --armor).

    Usually, --output=signed.gpg and --output signed.gpg are equivalent. (But not always – e.g. curl does not accept the former, only the latter.)

    (If I recall correctly, long options used + as the prefix before it was changed to --.)

  • The POSIX specification has a section Utility Argument Syntax, which describes the one-character options.


Most Windows programs use their own parsers, driving users mad.

  • Some require /a /b /c, others allow VMS-style /a/b/c, yet others prefer Unix-style /abc.
  • Most use / as prefix, some also accept -, others accept only -.
  • Values can be given as /foo bar, /foo=bar, /foo:bar.
  • Usually spaces can be /quoted "like this", but some programs take the " as a literal character. (This is a downside of letting the program do its own word-splitting; in Unix this is handled by the shell.)
  • Cross-platform programs may use an implementation of getopt.

Solution 2:

Generally the first is found in older programs which are too well entrenched to change. Those kind of long options are incompatible with the standard getopt() function.

The second style was introduced by GNU getopt_long(), and is compliant with existing standards which expect the first style to be bundled short options (that is, -orange is expected to mean -o -r -a -n -g -e). This style of long option is strongly preferred.