Here documents

Here Documents is a way of including, in your shell script, snippets of text verbatim. For example, if I needed to write a paragraph:

echo "paragraph start"
echo "..."
echo "..."
echo "paragraph end"
            

or

echo "paragraph start
...
...
paragraph end"
            
[Note] Note

These are different methods of producing the same output.

However, notice that this could become rather problematic with repetitive echo commands, or if the text has lots of special characters.

cat << END-OF-INPUT
...
...
...
END-OF-INPUT
            

'END-OF-INPUT' is just a string denoting the end of the text in this here document. The document reads until "here" and in this case here = 'END-OF-INPUT'. It could've been called anything as long as it is a matching 'tag' to signal the end of the input.

Let's try this on the command line. Type:

cat << EOF
This is the first line of our HERE document.
An the second. What happened to $USER
OK. Enough is enough.
Bye.

EOF
            

This is used extensively in shell archives (shar). In shar's the contents of the shell are the contents of the script itself.

We might want to count the number of lines in a here document:

wc -l << EOF
...
...
EOF
            

This would count the number of lines typed on the command line. So here documents are very useful and can be used to do many things. Create a script 'mailmsg.sh' with the contents:

mail -s "An Automated message from $USER" $1 << EOT
This is a
mail message
done!
EOT
            

Now run it:

	
mailmsg.sh hamish
            

I use this extensively in my shell scripts. We're going to modify oureatout.sh to produce some convenient message at the start of our script:

#!/bin/ksh
trap "Can't do that" 2

if [ $# -lt 1 ]
then
	cat <<END-OF-TEXT
	This is a simple lookup program 
	for good (and bad) restaurants
	in Cape Town.
	
	Usage: eatout.sh [-x] [-h] [-r rating] [-t type]
	-x will produce text output
	-h will produce HTML output viewable in a web browser
	-r specifies the rating. We suggest only using >5!
	-t specify the type of resturant (italian, smart, steakhouse, etc.)
	END-OF-TEXT	
...
exit 0
            

That would print out a little banner at the beginning of the script if the user does not call it with the correct parameters.

You can also use here documents to create vi documents, automated ftp sessions. In fact they are a very useful construct. We could:

USER=hamish
cat << EOT
echo $USER
pwd
hostname
EOT
            

Seeing the contents of each one of these is a command, it's going to echo each of these commands as part of the here document. The here document was able to interpret the $USER, I could redirect those commands and say:

USER=hamish
cat << EOT >out.sh
echo $USER
pwd
hostname
EOT

chmod +x out.sh
./out.sh
            

So our script created a new script called out.sh, changed it's mode and executed it.

Here's an example of using a HERE document to vi a file.[22]

#!/bin/bash
TARGETFILE=$1
# Insert 2 lines in file, then save.
#--------Begin here document-----------#
vi $TARGETFILE <<x23LimitStringx23
i
This is line 1 of the example file.
This is line 2 of the example file.
^[
ZZ
x23LimitStringx23
#----------End here document-----------#

#  Note that ^[ above is a literal escape
#  typed by Control-V <Esc>.

#  Bram Moolenaar (the author of vim) points out that this may not
#  work with 'vim', because of possible problems with terminal interaction.
            

Remember, our earlier HTML script? We could create the HTML table using a here document rather than echo'ing it:

cat << TABLE
<TABLE BORDER="1">
	<TR>
		<TD>$value1</TD>
		<TD>$value2</TD>
	</TR>
</TABLE>	TABLE
            

So here Documents can be used for a variety of things including SHAR, simplifying your text output or automating ftp logins and file transfers.

Amongst other things. I encourage you to attempt the exercises as well as modifying your existing scripts, to see how you can achieve the same output using here documents rather than the echo command.

Exercises

  1. Write a script that will itself create a script, which will automatically logout users who have been idle for longer than 15 minutes. Hint: Consult the example above.

  2. Using HERE documents, write a script that will generate a table 3x2 in size. Ensure that each block contains a picture or animated gif. There are a couple of gifs provided with this course. Alternatively, you can download your own. I found those from

  3. Modify your eatout.sh script to include a usage section. Give the user the option of using a -? as a means of printing the usage information.



[22] Thanks to Mendel Cooper - The advanced bash shell scripting guide (http://www.tldp.org/) for this excellent example of using a here document