If you’ve ever used wget to download a config file, tested commands on Ubuntu 24.04.4, searched logs with locate, monitored processes with top, created directories with mkdir, or even executed scripts as the nobody user for security testing, you already know how powerful the Linux command line can be. But there’s one Bash feature that many users overlook — and once you start using it, your scripts become dramatically cleaner and more powerful: Heredoc.
In this in-depth guide, I’ll walk you through everything you need to know about using Heredoc inside Bash scripts. We’ll cover syntax, variable behavior, redirection, indentation tricks, security considerations, advanced patterns, and real-world examples.
This article is written from hands-on experience — the goal is not just to explain heredocs, but to help you actually use them confidently in production scripts.
What Is a Heredoc in Bash?
A Heredoc (short for Here Document) is a type of input redirection that allows you to pass multiple lines of text to a command directly inside your script.
Instead of writing long echo chains or creating temporary files, you can embed structured multi-line content directly inside your Bash script.
Basic syntax:
command <<DELIMITER
text
text
DELIMITER
Everything between <<DELIMITER and the closing DELIMITER is passed to the command’s standard input.
Why Use Heredoc?
Here’s why I personally prefer heredocs over multiple echo statements:
- Cleaner and easier to read
- Ideal for configuration files
- Great for SQL queries
- Perfect for multi-line messages
- Easier automation scripting
- Useful in SSH remote execution
- Supports variable expansion (when needed)
- Can disable expansion for literal output
If you’re writing scripts that generate files or execute remote commands, heredocs are essential.
Basic Heredoc Example
Let’s start with something simple — printing multi-line text:
cat <<EOF
Hello,
This is a heredoc example.
It allows multiple lines.
EOF
Output:
Hello,
This is a heredoc example.
It allows multiple lines.
cat receives everything between the two EOF markers.
You can replace EOF with any word you like:
cat <<MYTEXT
Custom delimiter example
MYTEXT
The delimiter just has to match at the beginning and end.
Writing to a File Using Heredoc
One of the most common use cases: generating configuration files.
cat <<EOF > config.txt
username=admin
password=secret
port=8080
EOF
This will create (or overwrite) config.txt.
To append instead:
cat <<EOF >> config.txt
new_setting=true
EOF
This is much cleaner than using multiple echo commands.
Using Variables Inside Heredoc
By default, variables are expanded.
name="IdoLinux"
cat <<EOF
Welcome to $name
Today is $(date)
EOF
Output includes the variable values.
This makes heredocs powerful for dynamic file generation.
Preventing Variable Expansion
Sometimes you need to output literal text — like $PATH or $(command).
To prevent expansion, quote the delimiter:
cat <<'EOF'
The variable $USER will not expand.
Command substitution $(date) will not run.
EOF
Using single quotes around the delimiter disables:
- Variable expansion
- Command substitution
- Arithmetic expansion
This is critical when generating scripts or config templates.
Indented Heredoc with <<-
If you want your script to stay visually clean, use:
cat <<-EOF
This line is indented with tabs.
Bash removes leading tabs.
EOF
Important note:
- Only tabs are stripped
- Spaces will not be removed
This helps maintain script readability.
Using Heredoc with sudo or Another User
A common mistake is:
sudo cat <<EOF > /etc/file.conf
...
EOF
This fails because redirection happens before sudo.
Correct approach:
sudo tee /etc/file.conf > /dev/null <<EOF
secure_config=true
EOF
Or:
sudo bash -c 'cat <<EOF > /etc/file.conf
secure_config=true
EOF'
If you’re testing as the nobody user:
sudo -u nobody bash <<EOF
whoami
EOF
This executes the heredoc as another user safely.
Using Heredoc with SSH
This is one of my favorite uses:
ssh user@server <<EOF
mkdir /tmp/testdir
echo "Hello from remote server" > /tmp/testdir/file.txt
EOF
The commands inside the heredoc execute remotely.
If variables should expand locally:
VAR="LocalValue"
ssh user@server <<EOF
echo $VAR
EOF
If variables should expand remotely:
ssh user@server <<'EOF'
echo $HOSTNAME
EOF
The difference matters.
Passing Variables into a Heredoc Safely
Sometimes you want selective expansion.
Example:
name="Server1"
cat <<EOF
server_name=$name
literal_dollar=\$HOME
EOF
Or escape specific characters using backslashes:
cat <<EOF
This is \$PATH
EOF
You control expansion carefully depending on use case.
Heredoc with SQL Queries
Very common in admin scripts:
mysql -u root -p <<EOF
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE users (id INT, name VARCHAR(50));
EOF
This avoids external SQL files.
Generating Scripts with Heredoc
You can even create another script:
cat <<EOF > deploy.sh
#!/bin/bash
echo "Deployment started"
date
EOF
chmod +x deploy.sh
This is often used in automation environments.
Heredoc vs Here String
Don’t confuse heredocs with Here Strings.
Heredoc:
command <<EOF
multiple lines
EOF
Here string:
command <<< "single line input"
Heredoc = multi-line
Here string = single line
Common Errors and Debugging Tips
1. Delimiter Not Matching
The closing delimiter must:
- Be alone on the line
- Have no trailing spaces
- Match exactly
Wrong:
EOF
Correct:
EOF
2. Unexpected Variable Expansion
If you see unintended variable values:
- Quote the delimiter
- Escape
$with\
3. Indentation Not Working
Remember:
<<-EOF removes tabs, not spaces.
Security Considerations
Be careful when injecting variables into heredocs, especially if input comes from users.
Bad practice:
cat <<EOF > file.txt
$username
EOF
If $username comes from untrusted input, validate or sanitize it first.
Also, when writing into system directories like /etc, always verify permissions and use sudo tee if needed.
Advanced Pattern: Combining Heredoc with Functions
You can embed heredocs inside functions:
generate_config() {
cat <<EOF
app_name=$1
env=production
EOF
}
generate_config "MyApp"
Clean and reusable.
When Should You Use Heredoc?
Use heredocs when:
- Generating config files
- Running remote SSH blocks
- Passing SQL commands
- Writing automation scripts
- Creating large multi-line outputs
- Producing formatted CLI messages
- Bootstrapping environments
Avoid when:
- Only one line is needed (use here-string)
- Content is extremely large (use template file instead)
Practical Real-World Example
Here’s a small real automation scenario:
#!/bin/bash
PROJECT="demo_app"
mkdir -p /tmp/$PROJECT
cat <<EOF > /tmp/$PROJECT/README.md
# $PROJECT
Created on $(date)
This directory was automatically generated.
EOF
echo "Project structure created successfully."
Clean, readable, and self-contained.
Final Thoughts
Heredocs are one of those Bash features that feel optional — until you start using them properly. Then you wonder how you ever wrote clean automation scripts without them.
They make:
- Config generation easier
- Remote execution clearer
- Scripts more readable
- Multi-line handling elegant
- Automation more professional
If you’re serious about writing maintainable Bash scripts on modern Linux systems (including Ubuntu 24.04.4 and beyond), mastering heredocs is not optional — it’s essential.
Start small. Replace your next block of repeated echo commands with a heredoc. You’ll immediately notice the difference.
Happy scripting.






Pingback: How To Use cURL Like a Pro - iDoLinux
Pingback: Detecting and Checking Rootkits on Linux with Chkrootkit and RKHunter (Complete Technical Guide) - iDoLinux
Pingback: How to Redirect stdout and stderr in Bash (Complete Guide) - iDoLinux