echo trick to pipe to an interactive command, such as
bc, makes for a quick one-liner at the command line, it isn't practical for multiple-line input, such as when the contents of an actual file might be used. But there's another useful way to do this. The shell has a facility called here documents, or inline input, which is a great way to construct a file on the fly, such as inside of a script, and redirect the contents of this file to a command.
Specify a here document using the shell
<< operator and follow it on the same line with a limit string, which is the string that marks the termination of input and can be any text you choose, so long as it's a single word without space characters. Follow this with the lines of input that constitute your input file, and terminate the input with the limit string on a line of its own -- it
can't have any text before or after it, or that line is considered to be part of the input. Try it with
cat, as shown in Listing 11.
Listing 11. Making a here document
$ cat << END > END of input text > ENDspace > This is still not the END > ENDING SOON > THE END > END END of input text END This is still not the END ENDING SOON THE END $
The limit string, in this case
END, can appear anywhere in the input -- only when it appears on a line of its own with no spaces or other characters does it function as the termination of input.
Inline input is often used in scripts to output usage information to standard output. This is normally done by sending a here document
cat, as in the script in Listing 12. Use
vi to type it in and save it to a file named baseconv, and make the file executable (see the Make a shell script section).
Listing 12. Using a here document to give shell script usage information
#!/bin/sh cat << EOF baseconv is a program to convert a number from one base to another. Usage: baseconv [options] Options: -i BASE input base -o BASE output base -h display this message For more information, consult the baseconv man page. EOF
When the script is executed, the contents of the here document is sent (using
cat) to the standard output. Try it now, as shown in Listing 13.
Listing 13. Output of shell script usage information from a here document
$ baseconv baseconv is a program to convert a number from one base to another. Usage: baseconv [options] Options: -i BASE input base -o BASE output base -h display this message For more information, consult the baseconv man page. $
Additionally, most implementations of the Bourne shell recognize inline input redirected with the optional hyphen character. The optional hyphen character removes all leading tab characters from the beginning of all input lines, as well as the line containing the limit string itself. This is helpful when writing scripts where you want to keep the current indentation. Because inline input is normally taken literally and the limit string has to be given at the beginning of the line, the input would break your current indentation and make the script look unsightly. Thus, you can rewrite the script in Listing 12 to match Listing 14, and the output will be identical.
Listing 14. A shell script here document with leading indentation
#!/bin/sh cat <<- EOF baseconv is a program to convert a number from one base to another. Usage: baseconv [options] Options: -i BASE input base -o BASE output base -h display this message For more information, consult the baseconv man page. EOF
At the command line, inline input is used with one-liners that call an interactive program, such as the
bc calculator discussed in the Base conversion using
section. You can use a here document
to substitute a real file, or any number of lines of real input, for any interactive command.
Try sending multi-line input to
bc with a here document. Type what's shown in Listing 15.
Listing 15. Sending inline input to an interactive program
$ bc << EOF > ibase=16 > A > EOF 10 $
Variables are normally expanded with inline input. Try what's shown in Listing 16.
Listing 16. How variable expansion occurs in inline input
$ BASECON=16 $ bc << EOF > ibase=16 > $BASECON > EOF 22 $