A here document, commonly known as a heredoc, is a code section that directs a command list to an interactive program or command through the input stream. Widely supported in Unix shells like bash, zsh, ksh, and csh, heredoc is frequently utilized with commands such as ssh, sftp, cat, and tee.
Heredoc enhances the organization and efficiency of shell scripts, particularly beneficial for executing multiple commands seamlessly. In this tutorial, we'll explore its practical applications and features using straightforward examples.
Let’s get started!
Syntax
Heredoc uses the following form of syntax:
some command << delimiter
Heredoc block of code
delimiter
It requires the <<
redirection operator and a delimiter token. The delimiter token can be anything unique. Usually, it’s named EOF
or END
.
Example Usages
Multi-line sftp commands
To understand the benefits of using heredoc, let’s take a look at the following script:
This program executes multiple sftp
commands. At first, it creates a file in your local tmp
directory. Then it uses the sftp
command to transfer the file to a remote server. Suppose that you have a remote file named file
. The script will remove it and replace it with the newly uploaded file.
Save the script as a .sh
file and run it in your terminal. Note that I’ve set up an SSH key to log into my remote server. Therefore, I don’t need to provide a password.
This is the output:
$bash simple_script.shsftp> put /tmp/somefile /home/user/file_tmp
sftp> -rm /home/user/file
sftp> rename /home/user/file_tmp /home/user/file
sftp> quit
There is nothing wrong with this approach. However, it could be more elegant.
Here is how to rewrite the script using heredoc:
Execute the script:
As you can see, the results are the same. Now compare the two scripts. The second one is much tidier, isn’t it?
Multi-line commands with ssh
Let’s see how to take advantage of heredoc’s features when using ssh
. Suppose that you want to execute multiple commands (e.g. creating directories on a remote server). You would do something like this:
ssh -T user@host "mkdir /home/user/dir1"
ssh -T user@host "mkdir /home/user/dir2"
This will work. However, you have to execute the ssh
command multiple times, which is not so efficient.
Heredoc’s way to do it would look like this:
ssh -T user@host << EOF
mkdir /home/user/dir1
mkdir /home/user/dir2
EOF
Multi-line commands with cat
Let’s check out another useful example. Heredoc is handy when combined with the cat
command. You can pass multiple commands to cat
and execute them as a single command or script:
cat << EOF
The current date and time is: $(date)
The current kernel version is: $(uname -r)
The current directory is: $PWD
EOF
Output:
The current date and time is: Sat Jan 9 16:09:06 CET 2021
The current kernel version is: 19.6.0
The current directory is: /home/user/heredoc
Keep in mind that if you quote the delimiter, the parameters won’t be resolved:
cat << "EOF"
The current date and time is: $(date)
The current kernel version is: $(uname -r)
The current directory is: $PWD
EOF
Output:
The current date and time is: $(date)
The current kernel version is: $(uname -r)
The current directory is: $PWD
Parameter and command substitution
Heredoc accepts parameter and command substitutions. For example, we’ve already used {user}
as a parameter substitution in our sftp
program. Another example is the $date
command we just used above.
Suppress tab indentations
With heredoc, you can suppress tab indentations. This is simply done by adding a -
to the redirecting operator:
cat <<-EOF
First line
Second line
EOF
This results in:
First line
Second line
Neat comments
Another useful feature of heredoc is that you can make your comments inside your script more readable. Imagine that you have to write a long comment. Normally, you would put a #
sign in front of each comment line. Heredoc makes it more elegant by using the :
command like this:
: <<'EOF'
This is a test comment
to demonstrate heredoc
features
EOF
Conclusion
In this tutorial, we've explored the robust capabilities of heredoc.
Now equipped with the knowledge to execute multiple commands efficiently and elegantly, write clearer comments, and perform parameter and command substitutions in heredoc scripts.
Thank you for reading!