< Previous | Contents | Next >
Here Documents
We’ve looked at two different methods of outputting our text, both using the echo com-
mand. There is a third way called a here document or here script. A here document is an additional form of I/O redirection in which we embed a body of text into our script and feed it into the standard input of a command. It works like this:
command << token
text
token
where command is the name of command that accepts standard input and token is a string used to indicate the end of the embedded text. We’ll modify our script to use a here docu- ment:
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z")
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
cat << _EOF_
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
<BODY>
<H1>$TITLE</H1>
<P>$TIMESTAMP</P>
</BODY>
</HTML>
_EOF_
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z")
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
cat << _EOF_
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
<BODY>
<H1>$TITLE</H1>
<P>$TIMESTAMP</P>
</BODY>
</HTML>
_EOF_
Instead of using echo, our script now uses cat and a here document. The string _EOF_ (meaning “End Of File,” a common convention) was selected as the token, and marks the end of the embedded text. Note that the token must appear alone and that there must not be trailing spaces on the line.
So what’s the advantage of using a here document? It’s mostly the same as echo, except that, by default, single and double quotes within here documents lose their special mean- ing to the shell. Here is a command line example:
[me@linuxbox ~]$ foo="some text"
[me@linuxbox ~]$ cat << _EOF_
> $foo
[me@linuxbox ~]$ foo="some text"
[me@linuxbox ~]$ cat << _EOF_
> $foo
> "$foo"
> '$foo'
> \$foo
> _EOF_ some text "some text" 'some text'
$foo
> "$foo"
> '$foo'
> \$foo
> _EOF_ some text "some text" 'some text'
$foo
As we can see, the shell pays no attention to the quotation marks. It treats them as ordi- nary characters. This allows us to embed quotes freely within a here document. This could turn out to be handy for our report program.
Here documents can be used with any command that accepts standard input. In this ex- ample, we use a here document to pass a series of commands to the ftp program in or- der to retrieve a file from a remote FTP server:
#!/bin/bash
# Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz
ftp -n << _EOF_ open $FTP_SERVER
user anonymous me@linuxbox cd $FTP_PATH
hash
get $REMOTE_FILE bye
_EOF_
ls -l $REMOTE_FILE
#!/bin/bash
# Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz
ftp -n << _EOF_ open $FTP_SERVER
user anonymous me@linuxbox cd $FTP_PATH
hash
get $REMOTE_FILE bye
_EOF_
ls -l $REMOTE_FILE
If we change the redirection operator from “<<” to “<<-”, the shell will ignore leading tab characters in the here document. This allows a here document to be indented, which can improve readability:
#!/bin/bash
# Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org
#!/bin/bash
# Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz
ftp -n <<- _EOF_ open $FTP_SERVER
user anonymous me@linuxbox cd $FTP_PATH
hash
get $REMOTE_FILE bye
_EOF_
ls -l $REMOTE_FILE
FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz
ftp -n <<- _EOF_ open $FTP_SERVER
user anonymous me@linuxbox cd $FTP_PATH
hash
get $REMOTE_FILE bye
_EOF_
ls -l $REMOTE_FILE