What does the last "-" (hyphen) mean in options of `bash`?

Bash behaves in somewhat non-standard way when it comes to -.

POSIX says:

Guideline 10:
The first -- argument that is not an option-argument should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the - character.

[…]

Guideline 13:
For utilities that use operands to represent files to be opened for either reading or writing, the - operand should be used to mean only standard input (or standard output when it is clear from context that an output file is being specified) or a file named -.

And

Where a utility described in the Shell and Utilities volume of POSIX.1-2017 as conforming to these guidelines is required to accept, or not to accept, the operand - to mean standard input or output, this usage is explained in the OPERANDS section. Otherwise, if such a utility uses operands to represent files, it is implementation-defined whether the operand - stands for standard input (or standard output), or for a file named -.

But then man 1 bash reads:

A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --.

So for Bash - means neither standard input nor a file, hence somewhat non-standard.

Now your particular case:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

I suspect the author of this command may not realize - is equivalent to -- in this case. I suspect the author wanted to make sure bash will read from its standard input, they expected - to work according to the guideline 13.

But even if it worked according to the guideline, - would be unnecessary here because bash detects when its standard input is a pipe and acts accordingly (unless -c is given etc.).

Yet - doesn't work according to the guideline, it works like --. Still -- is unnecessary here because there are no arguments after it.

In my opinion the last - changes nothing. The command would work without it.

To see how -- and - can be useful in general, study the example below.


cat in my Kubuntu obeys both guidelines and I will use it to demonstrate usefulness of - and --.

Let a file named foo exist. This will print the file:

cat foo

Let a file named --help exist. This won't print the file:

cat --help

But this will print the file named --help:

cat -- --help

This will concatenate the file named --help with whatever comes from the standard input:

cat -- --help -

It seems you don't really need --, because you can always pass ./--help which will be interpreted as a file for sure. But consider

cat "$file"

when you don't know beforehand what the content of the variable is. You cannot just prepend ./ to it, because it may be an absolute path and ./ would break it. On the other hand it may be a file named --help (because why not?). In this case -- is very useful; this is a lot more robust command:

cat -- "$file"

In man bash, at the end of the single-character options there is:-

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.

If you have quoted the complete command, I can see no reason to use - after bash in this instance, but it does no harm.