2.23. Here Documents

We often want to output multiple lines of text from a script, for instance to provide detailed instructions to the user. For instance, the output below is a real example from a script that generates random passphrases.

===========================================================================
If no one can see your computer screen right now, you may use one of the
suggested passphrases about to be displayed.  Otherwise, make up one of
your own consisting of three words separated by random characters and
modified with a random capital letters or other characters inserted.
===========================================================================
	

We could output this text using six printf statements. This would be messy, though, and would require quotes around each line of text.

We could also store it in a separate file and display it with the cat command:

#!/bin/sh -e

cat instructions.txt
	

This would mean keeping track of multiple files, however.

A "here document", or "heredoc", is another form of redirection that is typically only used in scripts. It essentially redirects the standard input to a portion of the script itself. The general for is as follows:

command << end-of-document-marker

end-of-document-marker
	

The end-of-document-marker can be any arbitrary text that you choose. This allows the text to contain literally anything. You simply have to choose a marker that it not in the text you want to display. Common markers are EOM (end of message) or EOF (end of file).

Heredocs can be used with any Unix command that reads from standard input, but are most often used with the cat command:

#!/bin/sh -e

cat << EOM
===========================================================================
If no one can see your computer screen right now, you may use one of the
suggested passphrases about to be displayed.  Otherwise, make up one of
your own consisting of three words separated by random characters and
modified with a random capital letters or other characters inserted.
===========================================================================
EOM
	

Heredocs can also be used to create files from a template that uses shell or environment variables. Any variable references that appear within the text of a heredoc will be expanded. The output of any command reading from a heredoc can, of course, be redirected to a file or other device.

#!/bin/csh -ef

# Generate a series of test input files with difference ending values
foreach end_value (10 100 1000 10000)
    foreach tolerance (0.0001 0.0005 0.001)
        cat << EOM > test-input-$end_value-$tolerance.txt
start_value=1
end_value=$end_value
tolerance=$tolerance
EOM
    end
end