I have seen this explained somewhere before but can't find a reference now. An example usage from docker getting started guide for Ubuntu:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

I even recall very vaguely what it is supposed to do. IIRC correctly, it is supposed to somehow use the stdin passed through the pipe. But why is this necessary in this case?

The closest I came to finding anything about this was in this article: http://www.catonmat.net/blog/bash-one-liners-explained-part-three/. Maybe, it's related to closing a stream, like in the example where you open a non-standard stream and then close it?

exec 3<file
exec 3>&-

It's not a feature of Bash, or any shell, but a convention in many applications to explicitly tell them to read from stdin. Of course many programs read stdin if no other file is mentioned, but even in that case, you need to be able to explicitly specify stdin if you want it to be processed along with other files. E.g., cat foo - to have cat read both the file foo, and stdin.

In the case of apt-key, the man page implies that giving a filename for the add subcommand is mandatory, and that - must be specified to use stdin. Remember that it's up to the application to do what it wants, and read whatever input it desires; there's nothing that requires any program to read stdin. Using it as the default source for input is just a custom.

Some programs don't support - as meaning stdin, but take it as a literal filename. In those cases, workarounds like /dev/stdin are necessary.

As for >&-, I can't see they would be explicitly connected. It's probably just a somewhat coincidental use of a simple character. In >&- the dash probably comes from a connection with a strike meaning "nothing", an empty field. Why it's used to mean stdin, I don't know. But it looks nicer than % or such, and a number of other characters have other meanings.


The - is an argument that usually (for some commands) means "the stdin input".

So, this command pipe (two commands separated by a |):

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

use the - to tell apt-key to read from the stdin.

That input (stdin) is the one that comes from the pipe. The output of curl.

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.