Eof Bash: What Is It and How Does It Work?

Have you ever come across the term EOF in a Bash script and wondered what it means or how to utilize this feature effectively? If you've found yourself asking these questions, then you're in the right place.

In this blog post, we’ll dive deep into the concept of EOF in Bash, explaining what it is and how it works. We’ll look at its role within Bash here documents and explore how EOF affects variable and command substitution within these documents. Additionally, we'll discuss how the use of EOF impacts indentation in here documents. Let’s get started!

Prerequisite

To try out the scripts in this blog post, you need access to a Bash shell. You also need a text editor, such as "nano" or "vim", which come pre-installed by default in many Unix-like operating systems.

For the purpose of this blog post, I'll be using KodeKloud’s Ubuntu playground, which lets you access a pre-installed Ubuntu operating system in just one click. Best of all, you won't need to go through the hassle of installing any additional software— everything you need is already set up and ready to use.

Create a Script File

Let’s start by creating a Bash script file named demo.sh. This is where we'll place and run the scripts we're about to write in the upcoming sections. To create it, run the following command:

touch /usr/local/bin/demo.sh

Note: While you're free to create the demo.sh file in any directory of your choice, we're placing it in the /usr/local/bin directory for a specific reason. In most Linux distributions, this directory is included in the system's command path. This means we can run our script without making it executable.

With the script file created, let’s move on to the next section.

What Is EOF in Bash?

In Bash, you’ll often encounter the term EOF in the context of a here document. So, to fully understand EOF, we must first understand the concept of a here document.

A here document, often abbreviated as "heredoc", is a special type of redirection in Bash scripting that allows you to pass multiline strings of text directly into a command. Redirection is essentially a way of 'directing' data from one place to another.

The basic syntax looks like this:

command <<DELIMITER
line1
line2
DELIMITER

In this syntax, <<DELIMITER indicates the start of the here document. Bash will take the lines that follow as standard input to the command until it encounters a line containing only DELIMITER (no leading or trailing whitespace), which signals the end of the here document.

By convention, this delimiter is often represented as EOF (stands for "End of File"), though it can technically be any unique string that doesn't appear within the input text itself. Note that the opening and closing delimiters must be the same.

Now that you understand what EOF is in the context of a here document let's look at an example.

Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Running this command brings up the "nano" text editor in your terminal as follows:

Next, add the following script to the editor:

#!/bin/bash

cat <<EOF
Hello world!
This is a heredoc.
EOF

In this script, cat is the command that processes the here document. The <<EOF  initiates the here document, and the final EOF indicates its end. The text sandwiched between the EOFs ("Hello world! \n This is a heredoc.") is the input to the cat command, which subsequently prints it out.

Once you've added the script, you'll need to save your work and exit the "nano" editor. To save, press ctrl + o. You'll see a message asking for the File Name to Write. Just press enter to agree with the name that's already there. After your file is saved, you can leave "nano" by pressing ctrl + x.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see, each line of text between the <<-EOF and EOF" has been outputted exactly as it appears.

Quoted and Unquoted EOF in Bash Here Documents

There is a crucial aspect of here documents in Bash: whether variable and command substitution occurs depends on whether the EOF delimiter is quoted or unquoted. Let’s explore this concept further.

Unquoted EOF and variable/command substitution

When using an unquoted EOF as the delimiter in your here document, both variable and command substitutions are performed by default. In other words, when the delimiter (in our case, EOF) is not enclosed in quotes, any variables or commands inside the here document are automatically replaced with their values or outputs, respectively.

Let’s demonstrate this with an example. Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

WELCOME="Hello world!"
cat <<EOF
${WELCOME}
This is a heredoc.
Today is $(date).
EOF

In this script, we declare a variable named WELCOME with the value Hello world!.

Within the here document, we reference both the WELCOME variable and the date command. This is done using the ${WELCOME} syntax for variable reference and the $(date) syntax for command substitution.

Notice that there are no quotes around EOF. This means that both the variable and command substitution will be performed. That is, ${WELCOME} will be replaced by the value of the WELCOME variable ("Hello world!"), and $(date) will be replaced by the output of the date command, which is the current date and time.

After you've written the script in the "nano" editor, save your work by pressing ctrl+o. When prompted, confirm the filename by pressing enter. Finally, press ctrl+x to exit the editor.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see, the ${WELCOME} reference within the here document was replaced with the value of the WELCOME variable ("Hello world!"). Similarly, the $(date) command substitution was replaced with the output of the date command, which displays the current date and time.

This illustrates how the unquoted EOF in a here document allows for variable and command substitution in Bash, dynamically updating the content within the here document when the script is executed. It provides a powerful tool in script writing, allowing you to insert variable values and command outputs directly into blocks of text.

Quoted EOF and variable/command substitution

In the previous section, we learned that when the DELIMITER inside a here document is unquoted, variable and command substitution is performed by default. However, there are instances where you might want to prevent such substitutions, treating the content of the here document as literal text. How can you achieve this?

The solution is simple: by quoting the EOF delimiter. You can use either single quotes or double quotes around the EOF delimiter, like <<'EOF' or <<"EOF".

Let’s illustrate this concept with an example.  Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

WELCOME="Hello world!"
cat <<'EOF'
${WELCOME}
This is a heredoc.
Today is $(date).
EOF

This is the same script we used in our previous example, with one subtle change: we've enclosed the EOF delimiter in single quotes.

After you've written the script in the "nano" editor, save your work by pressing ctrl+o. When prompted, confirm the filename by pressing enter. Finally, press ctrl+x to exit the editor.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see, ${WELCOME} and $(date) were not replaced with their respective values. Instead, they remained as literal text within the output.

PRACTICE the concepts discussed here in a real-world live environment for FREE with KodeKloud Engineer.  Join thousands of students gaining real, hands-on experience by working on actual project tasks on a live system.

Managing Indentation in Here Documents With EOF

In Bash scripting, maintaining the readability of your code is crucial. Indenting code is a common practice to achieve this, but when it comes to here documents, leading spaces or tabs can become a part of your input, which might not be what you want. This is where the <<-EOF syntax comes into play.

By adding a hyphen (-) after << and before your delimiter, you instruct Bash to ignore any leading tabs (not spaces) in the here document. This feature lets you maintain the indentation of your script without these tabs being included in the text of the here document.

Let’s demonstrate this using an example. Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

cat <<-EOF
	Hello world!
	This is a heredoc.
EOF

Notice how the lines of the here document are indented with tabs. Because we used <<-EOF (added a hyphen before the delimiter), these leading tabs will be stripped out from the output.

After you've written the script in the "nano" editor, save your work by pressing ctrl+o. When prompted, confirm the filename by pressing enter. Finally, press ctrl+x to exit the editor.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see from the output, the leading tabs used for indentation within the here document have been stripped out, resulting in neatly aligned text.

It's important to note that this tab-stripping feature only applies to actual tab characters, not spaces. If you indent with spaces, those will still be included in the here document's text.

Looking to build a solid foundation in shell scripting? Check out this course from KodeKloud: Shell Scripts for Beginners.

Shell Scripts for Beginners | KodeKloud

Difference Between <<EOF and <<’EOF’

As discussed in the section "Quoted and Unquoted EOF in Bash Here Documents", the key difference between <<EOF and <<'EOF' (quotes around EOF) lies in how they handle variable and command substitution within the here document in Bash scripts.

When using an unquoted EOF delimiter (<<EOF), any variables or commands inside the here document are automatically replaced with their respective values or outputs.

On the contrary, if the EOF delimiter is quoted (<<'EOF'), variable and command substitution within the here document is prevented. In other words, the text within the here document is treated as literal text. Even if there are variable references or command substitutions present, they will not be evaluated but will appear exactly as they are in the script's output.

Difference Between <<EOF and <<-EOF

As discussed in the section "Managing Indentation in Here Documents With EOF", the difference between << and <<- in the context of EOF lies in how they handle leading tabs in the body of the here document.

When using <<EOF, any leading tabs or spaces before the lines of your here document will be included as part of the document. This means that if you are using indentation for code readability, this indentation will appear in the output of the here document.

On the other hand, if you use <<-EOF (notice there is a dash before the delimiter), Bash will ignore any leading tabs in the here document. This allows you to maintain the indentation of your script for readability without these tabs being included in the text of the here document.

However, it's important to note that this tab-stripping feature only applies to actual tab characters, not spaces. If you indent with spaces, those will still be included in the here document's text.

Looking to build a solid foundation in Bash scripting? Check out this course from KodeKloud: Advanced Bash Scripting.

Advance Bash Scripting | KodeKloud

Conclusion

In this blog post, we learned what EOF is and how it works within the context of Bash here documents. We also learned how the presence or absence of quotes around EOF influences the substitution of variables and commands within here documents. Furthermore, we discovered how to efficiently handle indentation by using a hyphen before the EOF delimiter, enabling us to dismiss leading tabs.

TEST your Linux expertise with our FREE, fun, and challenging set of hands-on challenges.

Find all our Bash Scripting and certification exam preparation courses in our Linux Learning Path.