Skip to main content
4 of 7
added 311 characters in body
Kusalananda
  • 356.1k
  • 42
  • 737
  • 1.1k

When cat is not given a filename on the command line (or if the filename is just -), then it switches to reading from its standard input.

That means that with

cat <<END something something END 

cat will notice that it was not given a filename and will proceed to read from the here-document, which is arriving on its standard input stream.

You can get cat to read from both its standard input and from a file with

cat - filename <<END something something END 

This will cause the contents of the here-document to be concatenated with the contents of filename. If the order of the arguments was filename - then that would be the order that the data would be concatenated too.

Note that - is not special in any way, and is handled in this way specifically by the cat utility. If you have an actual file called - that you need to run cat on, use cat ./-.


For all purposes, you can think of feeding a here-document directly into a utility as a shorthand for creating a temporary file and then invoking the utility with that attached to the standard input stream:

printf 'some contents' >tmpfile utility <tmpfile rm -f tmpfile 

Here-documents might not actually be implemented this way (it may be a FIFO (named pipe)), but that's not an entirely incorrect way of thinking about it.

Reading the bash sources, it seems as if that particular shell implements here-documents by creating a temporary file using the mkstemp() library function if it's available, otherwise it tries to create a random filename to write too. See redir.c and lib/sh/tmpfile.c in the bash source distribution.

Kusalananda
  • 356.1k
  • 42
  • 737
  • 1.1k