Why do console applications get the arguments started with either:

a) one dash (myapp -arg1 123; ls -al)
b) two dashes (myapp --arg1 123; git push origin master --force)
c) without dashes at all (myapp 123; man ls)
d) without dashes but with the equal sign (myapp arg1=123; dd if=/dev/zero)

Isn't there a standard convension? Even among the standard Linux applications all three cases a), b) and d) do exist at the same time. And it's tough to remember when I should use, for example, -help and when --help.


Dashes are used to denote options, which modify the behavior of the command. Arguments without dashes denote the main parameters of the command, often these are filenames.

Single hyphens usually introduce options consisting of just one letter. Multiple such options can be grouped together, so ls -a -l can be abbreviated as ls -al. This was the standard convention for most early Unix commands.

Double hyphens introduce options that are whole words. This convention is necessary to distinguish them from the grouping described above. This option style was popularized by the GNU versions of utilities, because they often had so many features that they ran out of mnemonic single letters.

Sometimes an option requires a parameter of its own. The styles of this vary: some commands use -o parameter, some use -oparameter, some use --option=parameter, and some allow multiple forms.

There are also a handful of commands that invented their own, ideosyncratic argument styles. These are typically very old commands, from before there was a concensus on argument conventions. Examples of this are tar and dd. find is also unusual in being an old command that used full word options before the -- convention was created; its arguments are practically a language of its own, because its needs don't fit into the typical command -options parameters paradigm.

Other reasons for variation among commands is that Unix did not originally have an argument parsing library function. It wasn't until well into its lifetime that the getopt and getopts functions were created. Using these libraries essentially forces you to follow common practices. But older programs did their own, ad hoc argument parsing, and different programmers made different decisions.


@Barmar is correct, but is missing a few points of information. Why this actually happens is solely because of how the program's code was written, and, more specifically, what was used to parse the arguments.

Before I talk more about that, I want to clear up some terminology. First of all, what you call "options" are actually also arguments. In fact, everything you type on the command-line is an argument (including the program's name). These arguments are then typically stored in an array (called argv in C). Then, the program chooses how to (or if to) parse these arguments and behave accordingly. Now, arguments typically take one of three shapes:

  1. flags (do not take an argument; simply turn a behavior on or off)
  2. switches (take an argument; modify behavior based on the argument)
  3. parameters (plain data not meant to modify behavior)

1 and 2 are often referred to as OPTIONS and are meant to change program behavior, but both appear in different styles (as also mentioned by Barmar). C's getopt library actually allows for a great deal of flexibility in this area. Though the convention is to have options be specified either as a single-letter preceded by a single hyphen or a full-word preceded by two hyphens, programs written with getopt actually allow for any of the following to be equivalent (assuming help is given h as the index):

-h, --h, --help

However, -help is actually not allowed by getopt (so, if a tool uses -help for its usage flag, then you can be pretty sure it wasn't written with the getopt library). This is because getopt interprets a single hypen to signal a list of combined options, so it interprets -help as -h -e -l -p.

Additionally, when options take arguments (conventionally called “optargs”), there are a few ways you can specify them. The following—given that the index for opt is o, and that opt requires an optarg¹—are all also equivalent:

-oParameter, -o Parameter, --opt=Parameter, --opt Parameter

Though the getopt library is a widely-used standard now, many tools that predate it (such as tar) still use their own parsing setup, hence why tar -xjf is equivalent to tar xjf.

TL;DR: getopt hasn't always been around, so programmers had to parse arguments their own way. But, newer tools typically use it so their behavior is sane and predictable.

1 There is a not-well-documented ability to have options be able to take an optarg but not require one. Optional optargs cause all sorts of annoying things and cause some of the more common ways of specifying options to be invalid (since they would be ambiguous). Luckily, arguments which take an optional argument are not too common.


options starts with dash, usually one letter, multiple options can specify

ls -l -h 
ls -lh

options starts with two dash, usually take words, multiple options can not work

ls --list --human

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.