3.24. Here Documents

A here document uses a special form of I/O redirection (see Section 3.13) to feed a command script to an interactive program, such as ftp, telnet, or ex. Typically, the script consists of a command list to the program, delineated by a limit string. The special symbol << precedes the limit string. This has the effect of redirecting the output of a file into the program, similar to
   1 interactive-program
   2 	< command-file
where command-file contains
   1 command #1
   2 command #2
   3 ...

The "here document" alternative looks like this:
   1 #!/bin/bash
   2 interactive-program <<LimitString
   3 command #1
   4 command #2
   5 ...
   6 LimitString

Choose a limit string sufficiently unusual that it will not occur anywhere in the command list and confuse matters.

Note that "here documents" may sometimes be used to good effect with non-interactive utilities and commands.


Example 3-93. dummyfile: Creates a 2-line dummy file

   1 #!/bin/bash
   2 
   3 # Non-interactive use of 'vi' to edit a file.
   4 # Emulates 'sed'.
   5 
   6 if [ -z $1 ]
   7 then
   8   echo "Usage: `basename $0` filename"
   9   exit 1
  10 fi
  11 
  12 TARGETFILE=$1
  13 
  14 vi $TARGETFILE <<x23LimitStringx23
  15 i
  16 This is line 1 of the example file.
  17 This is line 2 of the example file.
  18 ^[
  19 ZZ
  20 x23LimitStringx23
  21 
  22 # Note that ^[ above is a literal escape
  23 # typed by Control-V Escape
  24 
  25 exit 0

The above script could just as effectively have been implemented with ex, rather than vi. Here documents containing a list of ex commands are common enough to form their own category, known as ex scripts.


Example 3-94. broadcast: Sends message to everyone logged in

   1 #!/bin/bash
   2 
   3 wall <<zzz23EndOfMessagezzz23
   4 Dees ees a message frrom Central Headquarters:
   5 Do not keel moose!
   6 # Other message text goes here.
   7 # Note: Comment lines printed by 'wall'.
   8 zzz23EndOfMessagezzz23
   9 
  10 # Could have been done more efficiently by
  11 # wall <message-file
  12 
  13 exit 0


Example 3-95. Multi-line message using cat

   1 #!/bin/bash
   2 
   3 # 'echo' is fine for printing single line messages,
   4 #  but somewhat problematic for for message blocks.
   5 #  A 'cat' here document overcomes this limitation.
   6 
   7 cat <<End-of-message
   8 -------------------------------------
   9 This is line 1 of the message.
  10 This is line 2 of the message.
  11 This is line 3 of the message.
  12 This is line 4 of the message.
  13 This is the last line of the message.
  14 -------------------------------------
  15 End-of-message
  16 
  17 exit 0


Example 3-96. upload: Uploads a file pair to "Sunsite" incoming directory

   1 #!/bin/bash
   2 
   3 # upload
   4 # upload file pair (filename.lsm, filename.tar.gz)
   5 # to incoming directory at Sunsite
   6 
   7 
   8 if [ -z $1 ]
   9 then
  10   echo "Usage: `basename $0` filename"
  11   exit 1
  12 fi  
  13 
  14 
  15 Filename=`basename $1`
  16 # Strips pathname out of file name
  17 
  18 Server="metalab.unc.edu"
  19 Directory="/incoming/Linux"
  20 # These need not be hard-coded into script,
  21 # may instead be changed to command line argument.
  22 
  23 Password="your.e-mail.address"
  24 # Change above to suit.
  25 
  26 ftp -n $Server <<End-Of-Session
  27 # -n option disables auto-logon
  28 
  29 user anonymous $Password
  30 binary
  31 bell
  32 # Ring 'bell' after each file transfer
  33 cd $Directory
  34 put $Filename.lsm
  35 put $Filename.tar.gz
  36 bye
  37 End-Of-Session
  38 
  39 exit 0

Note

Some utilities will not work in a "here document". The pagers, more and less are among these.

For those tasks too complex for a "here document", consider using the expect scripting language, which is specifically tailored for feeding input into non-interactive programs.