Here Document
A "here document" is a Bourne shell syntactic feature that allows you to feed data to a program without storing it in an external file. It works equally well in POSIX, Korn and Bash shells too.
The basic form is:
somecommand <<WORD your data go here WORD
Here, somecommand can be any program that reads from standard input (cat is by far the most common), and WORD can be any delimiter word you like. (EOF is a common choice.) For example:
usage() { cat <<EOF usage: myprogram [-aqx] [-f configfile] An explanation of how mypgrogram is used goes here. There can be a much text as you want. EOF }
Here documents of this form have certain characteristics:
Shell substitutions (such as $variable) in the here document are performed.
- The delimiter word must appear on a line by itself, in the first column.
- Any whitespace in the here document is preserved, including leading whitespace.
- Command substitutions and parameter expansions do not need to be quoted in a here document; if they are, the quotes will be printed.
If we want to avoid shell substitutions, we can quote the delimiter word, or any part of it:
cat <<'WORD' Tickets are $20 if purchased in advance, or $25 at the door. Backticks `are literal` as well. WORD
If we want the body of the here document to be indented like the rest of the script while also having bash remove all leading tab characters during execution, we can add a - (hyphen) suffix to the immediate right of the '<<'. An empty space to the left of (either instance of) WORD is optional, but there may be no trailing blanks after the second delimiter.
usage() { cat <<- WORD usage: myprogram [-aqx] [-f configfile] This is an indented here document example. WORD
In this form, all leading tab characters (not spaces!) will be removed. There is no provision for removing leading spaces, or leading tabs-and-spaces. (Recall the syntactic restrictions of Makefiles, and you'll be OK.)
Here Strings
In bash, there is a variant of the here document called the here string. It's more compact, but also more limited:
IFS=. read -a octets <<< "$ipaddr"
The <<< serves a role similar to that of the << in a here document, but there is no sentinel word to tell us where the input ends. Rather, the <<< is followed by a single word (Quotes are your friend!). That word, plus a newline, become the standard input of the command.
Implementation Details
Here documents are typically implemented by creating a temporary file and redirecting standard input from this file when the program is invoked. However, shells are free to use other implementations as well. For example, bash 5.1 uses either a pipe or a temporary file, depending on the size of the text.
The temporary file implementation was used so universally for so long, however, that many scripts rely on it, feeding here document or here string text to a command that requires a seekable file as standard input. These scripts may break when upgrading bash.
If you're feeding text to a command that requires seekable input, you should create a temporary file explicitly rather than relying on historic implementations of here documents. Some shells offer a syntax that guarantees the creation of a temporary file; if your shell doesn't, then you may look for utilities like mktemp(1). BashFAQ/062 has some advice on this topic.