What's the difference between - (one hyphen) and -- (two hyphens) in a command?
Generally:
-
means to read the argument/content from STDIN (file descriptor 0)--
means end of command options, everything follows that are arguments
Why needed:
About -
:
$ echo foobar | cat -
foobar
Although cat
can read content from STDIN without needing the -
, many commands need that and their man
pages mention that explicitly.
Now about --
, I have created a file -spam
, let's cat
the file:
$ echo foobar >-spam
$ cat -spam
cat: invalid option -- 'p'
Try 'cat --help' for more information.
$ cat -- -spam
foobar
Without --
, cat
takes s
, p
, a
, m
all as it's options as they follow -
, --
explicitly indicates the end of option(s), after that -spam
is taken as a file name.
--
is the long name version-
is the short name version
Have a look at man ls
and some of the options:
-a, --all : do not ignore entries starting with .
-A, --almost-all : do not list implied . and ..
-b, --escape : print C-style escapes for nongraphic characters
-B, --ignore-backups : do not list implied entries ending with ~
They are the same but some prefer the short, some the long versions.
And both are there for compatibility. Removing an option breaks software.
Not every command follows this this. As @ Bakuriu mentions in comment: a command like find
has what you can consider "long names" with 1 hyphen.
In regards to coding there is something to note too:
- Bash's getopts does not support long names.
- The getopt from the GNU utils does.
This actually depends on the program concerned. There are standards, but they aren't actually enforced anywhere: it's up to each program to implement them.
The find
command, for example, takes full name parameters with single hyphens:
find . -iname "*.jpg" -delete
However, in general, double hyphens indicate a switch which is a full word, and single hyphens indicate a swich which is a single letter. And single-letter switches can be combined, which means that all of the following commands are equivalent:
cp --verbose --recursive /dir/from /dir/to
cp -v -r /dir/from /dir/to
cp -vr /dir/from /dir/to
A double hyphen followed by a space can also be used to indicate "this is the end of commands; everything that follows is a file name, even if it looks like a command".
And a single hyphen with no following letters can indicate "read from stdin, not from a file".
However, all of this is program-dependent. Any given program can violate any of these standards, as seen, for example, with find
.