4. Here documents
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 a command that accepts standard input and token is a string used to indicate the end of the embedded text. It should be at the beginning of the line and should have no trailing spaces.
-
Let's modify the script to use a here document:
vim sys_info.sh/echoPress capital
Oand type:cat << _EOF_Press ESC and then
Gandoto go to the end of the buffer and open a new line. Then type:_EOF_Press ESC and give this substitute command:
:%s/echo "//Gk$x:wqThe script now should look like this:
#!/bin/bash
# Program to output a system information page.
declare -r TITLE="System Information Report for $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIMESTAMP="Generated on $CURRENT_TIME, by $USER"
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIMESTAMP</p>
</body>
</html>
_EOF_./sys_info.shInstead of using
echo, the script now usescatand a here document. -
The advantage of a here document is that inside the text we can freely use single and double quotes, since they are not interpreted by the shell as delimiters of a string. For example:
foo="some text"cat << EOF
$foo
"$foo"
'$foo'
\$foo
EOFThe shell treats the quotation marks as ordinary characters.
-
We also notice that the variables inside the text are expanded. To prevent variable expansion we can enclose the token in quotes:
cat << "EOF"
$foo
"$foo"
'$foo'
\$foo
EOFcat << 'EOF'
$foo
"$foo"
'$foo'
\$foo
EOF -
Here documents can be used with any command that accepts standard input. For example we can use it with
ftpto retrieve a file:ftp1.sh#!/bin/bash
# Script to retrive a file via FTP
FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/bookworm/main/installer-amd64/current/images/cdrom/
REMOTE_FILE=debian-cd_info.tar.gz
ftp -n << _EOF_
open $FTP_SERVER
user anonymous me@linuxbox
cd $FTP_PATH
get $REMOTE_FILE
bye
_EOF_
ls -l $REMOTE_FILEvim ftp1.sh:q!./ftp1.shIf we change the redirection operator from
<<to<<-, the shell will ignore the leading tab characters in the here document. This allows a here document to be indented, which can improve readability.ftp2.sh#!/bin/bash
# Script to retrive a file via FTP
FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/bookworm/main/installer-amd64/current/images/cdrom/
REMOTE_FILE=debian-cd_info.tar.gz
ftp -n <<- _EOF_
open $FTP_SERVER
user anonymous me@linuxbox
cd $FTP_PATH
get $REMOTE_FILE
bye
_EOF_
ls -l $REMOTE_FILEvim ftp2.sh:q!./ftp2.sh