Bash by Example: Here Documents
Passing multi-line input to commands using here documents with the <<EOF syntax, feeding blocks of text into interactive programs, generating configuration files with variable expansion, disabling expansion with quoted delimiters, and using indented here documents with <<- for better code readability.
Code
#!/bin/bash
file="config.ini"
version="1.0.0"
# Basic Heredoc
# Variables ARE expanded
cat <<EOF > "$file"
[General]
AppVersion=$version
Author=$USER
Path=$PWD
EOF
echo "File created with variable expansion:"
cat "$file"
# Quoted Heredoc
# Variables are NOT expanded (treated literally)
cat <<'LIMIT_STRING' > raw.txt
This is raw text.
$version will appear literally as $version.
Backticks `date` will not execute.
LIMIT_STRING
echo -e "\nFile created with literal text:"
cat raw.txt
# Indented Heredoc (<<-)
# Strips leading tabs (but NOT spaces)
if true; then
cat <<-END
This line is indented with a tab in source.
But it prints without the tab.
(Only works if you use actual tabs!)
END
fi
rm "$file" raw.txtExplanation
A "Here Document" (Heredoc) is a special form of I/O redirection that allows you to embed a block of multi-line text directly into your script. It is essentially a way to pretend you are typing into the standard input of a command. The syntax is command <TOKEN on a line by itself.
Heredocs are incredibly useful for generating configuration files, creating help menus, or feeding commands into interactive programs like ftp or sql clients. By default, Bash expands variables inside the Heredoc, meaning $VAR will be replaced by its value. This makes it a powerful templating engine.
If you want to disable variable expansion (for example, if you are generating another Bash script or a file containing $ signs), you simply quote the delimiter: <<'EOF'. There is also the <<-EOF variant, which strips leading tab characters. This allows you to indent the Heredoc inside if blocks or loops for better code readability without messing up the output format.
Code Breakdown
$version and $USER are replaced by their actual values before cat sees them.<<'LIMIT_STRING'. The quotes tell Bash "do not touch anything inside this block". Useful for writing code or regex patterns.<<-END allows indentation. Note that it only strips tabs, not spaces. If your editor converts tabs to spaces, this might not work as expected.
