@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:
- flags (do not take an argument; simply turn a behavior on or off)
- switches (take an argument; modify behavior based on the argument)
- 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.