Introduction

Input/output redirection is an extremely important aspect of writing bash shell scripts and working with the bash shell command line interface in general. A here document is a form of I/O redirection that tells the bash shell to read input from the current source until a line containing only the delimiter is seen. This delimiter is known as the limit string.  The limit string is preceded by the symbol << followed by the input commands or lines that we wish to redirect. We type the limit string again once we are done writing the input statements/commands that are to be redirected to indicate the end of the here document. The effect of enclosing a set of commands is that is redirects the output of the command block into the stdin of the program or command to which the stdin is directed to.

Given below is the syntax for creating and using a here document:

Command <<MyUniqueLimitString
some text
some more text 
MyUniqueLimitString

In the above statements, the string MyUniqueLimitString serves as the limit string for the here document.

Note: There should not be any space between the << symbol and the limit string. If there are any characters between the limit string and the << symbol then the here document is unlikely to work. Also the limit string that terminates the here document should not have any space or other characters between it and the prompt. With a basic understanding of here documents, we’ll now look at a couple of examples to familiarize ourselves with their usage.

Example 1: Print some statements using cat.
The most frequent use of here documents is perhaps with the cat command. So, for our first example, let’s use here documents to redirect a bunch of lines to the input of the cat command.

[root@linuxnix ~]# cat <<EOF
> -----------------------
> This is a test statement
> to demonstrate the use of
> here documents
> -----------------------
> EOF
-----------------------
This is a test statement
to demonstrate the use of
here documents
-----------------------

Note that after we typed in the limit string preceded by <<, our shell prompt was changed. Once we typed the terminating limit string, the cat command displayed the lines that we fed to it on to stdout in this case the terminal.

 

Example 2: Save redirected lines to a file using cat
In our previous example, we used here documents to redirect some lines to cat command so that they could be displayed back to us on the terminal. But we could also save the output to a file instead of printing out to stdout i.e. we could use here documents and output redirection together which is actually very common. Let’s modify our previous example to redirect the content enclosed within the here document to a file named here.txt.

[root@linuxnix ~]# cat <<EOF > here.txt
> ----------------------------
> This is a test statement
> to demonstrate the use of
> here documents
> ----------------------------
> EOF
[root@linuxnix ~]# cat here.txt
----------------------------
This is a test statement
to demonstrate the use of
here documents
----------------------------

 

Example 3: Using here documents with for loops
We could use the combination of the cat command and here documents to generate a list and then iterate over that list using a for loop. Given below is an example

[root@linuxnix test]# for NAME in `cat <<EOF
> file12
> fil1e39
> file99343
> EOF`
> do touch $NAME; done
[root@linuxnix test]# ls
fil1e39 file12 file99343
[root@linuxnix test]#

In the above example, instead of adding the desired file names to a file first and then iterating over the resulting list we used here documents instead.

 

Example 4: Variable substitution within here documents
Any variables that we type within the here documents get interpolated to their corresponding values. Given below is an example.

[sahil@linuxnix:~] $ cat <<EOF > test.txt
> --------------------------------
> Your user name is $LOGNAME
> You are in $HOME
> --------------------------------
> EOF
[sahil@linuxnix:~] $
[sahil@linuxnix:~] $ cat test.txt
--------------------------------
Your user name is sahil
You are in /export/home/sahil
--------------------------------

As you may have observed from the example above, the variables $LOGNAME and $HOME were expanded to their corresponding values when the output was redirected to the file.

 

Example 5: Automating sftp commands within scripts
We can effectively use here documents to feed commands to an sftp session which otherwise would have been had to be typed in interactively. Given below is an example of doing this directly on the command line but you are likely to employ this method in your scripts using sftp.

[sahil@linuxnix:~] $ sftp linuxnix << EOF
> put test.txt /tmp
> cd /tmp
> quit
> EOF
Connecting to linuxnix...

sftp> put test.txt /tmp
Uploading test.txt to /tmp/test.txt
test.txt 100% 120 0.1KB/s 00:00
sftp> cd /tmp
sftp> quit
[sahil@linuxnix:~] $ ls -l /tmp/test.txt
-rw-r--r-- 1 sahil unix 120 Mar 3 12:27 /tmp/test.txt

In the above example, we typed in commands within the here document which fed the commands as input to the sftp command. As soon as the terminating delimiter string was encountered the sftp session began and the commands fed from the here document were executed successfully.

 

Conclusion

In this article we introduced you to here documents and then demonstrated some very practical use cases for here documents to illustrate how useful they could be to your everyday scripting activities. We hope that you’ve found the examples to be useful and we look forward towards your feedback.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.