Shell Here Document Overview

Here documents (also called here docs) allow a type of input redirection from some following text.  This is often used to embed a short document (such as help text) within a shell script.  Using a here doc is often easier and simpler than a series of echo or printf statements.  It can also be used to create shell archives (shar files), embed an FTP (or other) script that needs to be fed to some command (such as ftp), and a few other uses.  Here docs are so useful many other languages use them, such as Perl and Windows PowerShell.

The syntax is simple.  Use <<word on the command line.  Then all folllowing lines are collected by the shell (and treated as one very big word), up to a line that contains the word on a line by itself.  (No leading or trailing spaces or tabs allowed!)  That word is fed into the command's standard input.  Here's an example:

cat <<EOF
This is a here document.  All lines following the command,
up to a line containing the word (in this case, "EOF") are collected
and sent into the command's standard input.
EOF

The word used as a delimeter can be anything; EOF or END work well and are common, as is !.  If quoted, the delimeter word can contain white space, as shown here:

cat <<'    END'   # starts with 3 spaces
   Hello
   END

Note the delimeter word can appear inside the here doc, just not on a line by itself.  It is possible to have multiple here docs on a single command, but this is rarely useful.  The command's input is redirected from each here doc in order.

Using <<-word (a leading dash) will strip leading tabs (but not spaces).  (You can enter a tab by typing control-v then TAB.)  This feature was intended to allow you to indent here doc bodies to look nicer in a shell script, but problems with tabs (for example, automatic convertion to spaces) mean you're better off not using this feature.

The body of a here doc is expanded using shell's parameter expansions, command substitutions, and arithmetic expansions.  A backslash inside of a here doc behaves as if it were inside of double quotes; single and double quotes are just regular characters (they don't quote anything) in a here doc.  However, inside of an inner command ($(...)) or parameter expansion (${...}), a double quote keeps its normal shell meaning.  For example:

foo=bar
cat <<EOF
\$foo = "$foo",
but * (or another wild-card) is just a '*'.
Today is $(date "+%A").
EOF

Quoting of any part of word turns off these substitutions on the here document body.  The type of quoting doesn't matter: 'X', "X", or \X.  For example:

foo=bar
cat <<\EOF
\$foo = "$foo",
but * (or another wild-card) is just a '*'.
Today is $(date "+%A").
EOF

See also Here-Document description in the POSIX/SUS standard.