Multi-Line Comments in Bash Using : <<'COMMENT' ... COMMENT
Learning Focus
- Understand how to create multi-line comment blocks using
: <<'COMMENT' ... COMMENT. - Learn the purpose of the colon (
:) as a null command that discards input. - Differentiate between quoted and unquoted here-document delimiters.
- Explore three safe variations:
<<COMMENT,<<'COMMENT', and<<-"COMMENT". - Learn best practices for commenting, documentation, and testing Bash scripts safely.
- Apply this syntax for WordPress and VPS automation scripts for large annotated sections.
2. 5W + 1H Framework
| Element | Description |
|---|---|
| What | : <<'COMMENT' ... COMMENT uses a here-document redirected into the null command (:). Everything inside the block is read and discarded, functioning as a multi-line comment. |
| Why | To include large documentation blocks, disable multiple lines of code, or provide script explanations without execution. |
| Who | Bash users, sysadmins, and WordPress VPS maintainers writing or debugging large scripts. |
| When | During development, testing, or adding descriptive notes. |
| Where | Anywhere inside a Bash script. |
| How | Start with : <<'COMMENT', write your notes or code block, and close with COMMENT on its own line. |
3. Core Syntax & Concept
Syntax Formula
: <<'COMMENT'
Your text or code goes here.
All lines between start and end markers are ignored.
COMMENT
Behavior
:= null command that discards all input and returns success.<<= here-document operator.'COMMENT'= quoted delimiter to prevent$VARor$(command)expansion.- All text until the closing
COMMENTis ignored by Bash.
Example 1 — Basic Multi-Line Comment
#!/bin/bash
: <<'COMMENT'
This is a block of text ignored by Bash.
1. Backup database
2. Update WordPress plugins
3. Flush cache
COMMENT
echo "Maintenance started..."
Expected Output:
Maintenance started...
Explanation:
The lines inside the COMMENT block are redirected into :, which discards them silently.
Example 2 — Documentation Header
#!/bin/bash
: <<'COMMENT'
==============================================
Script : wpmaintain.sh
Purpose : Automate WordPress plugin updates
Author : Donny Ari W.
Version : 1.0
Date : 2025-10-12
==============================================
COMMENT
echo "→ Running WordPress maintenance..."
Expected Output:
→ Running WordPress maintenance...
Explanation: All descriptive text inside the comment block is for documentation only; Bash ignores it completely.
Example 3 — Temporarily Disable Code
#!/bin/bash
: <<'COMMENT'
wp plugin update --all --allow-root --path=/home/site/public_html
wp cache flush --allow-root --path=/home/site/public_html
COMMENT
echo "Plugin updates disabled during maintenance test."
Expected Output:
Plugin updates disabled during maintenance test.
Explanation: All commands inside the block are skipped; this is a safe way to disable sections during debugging.
Example 4 — Inside a Loop (Advanced Use)
for site in /home/*/*/public_html; do
: <<'COMMENT'
echo "→ Updating: $site"
wp plugin update --all --allow-root --path="$site"
COMMENT
echo "Checked: $site"
done
Expected Output:
Checked: /home/.../public_html
Checked: /home/.../public_html
Explanation: The comment block is parsed but ignored inside the loop — the rest executes normally.
4. Variations of the Syntax
| Variant | Example | Variable Expansion | Behavior | Use Case |
|---|---|---|---|---|
| Unquoted | : <<COMMENT | ✅ Expands $VAR and $(cmd) | Variables are expanded inside the block | When you want notes with evaluated values |
| Single-Quoted (Preferred) | : <<'COMMENT' | ❌ No expansion | All content treated literally | For safe documentation or disabled code |
| Double-Quoted (Indented) | : <<-"COMMENT" | ❌ No expansion + supports leading tabs | Easier formatting with indented comment text | For neatly aligned blocks in scripts |
Example of Each Variation
1️⃣ Unquoted (Expansion Enabled)
VAR="Expanded"
: <<COMMENT
This text will show $VAR and $(whoami)
COMMENT
Behavior: Variables expand — not a true “comment.”
2️⃣ Quoted (No Expansion, Safe for Comments)
: <<'COMMENT'
This text will show $VAR and $(whoami) literally.
COMMENT
Behavior: Everything inside is literal — true comment block.
3️⃣ Indented Quoted (Tabs Allowed)
: <<-"COMMENT"
This text block can be indented with tabs.
Variables like $VAR are not expanded.
COMMENT
Behavior: Same as 'COMMENT', but allows tab indentation (not spaces) before each line or the closing marker.
5. Implementation Steps
- Open or create your Bash script:
nano /root/wp-maintenance.sh
- Insert a documentation block:
: <<'COMMENT'
==========================================
WordPress VPS Maintenance Script
Tasks:
- Backup site
- Update plugins
- Purge cache
==========================================
COMMENT
- Add active commands below:
echo "Starting WordPress maintenance..."
- Save and execute:
chmod +x /root/wp-maintenance.sh
./root/wp-maintenance.sh
6. Best Practices
| Tip | Description |
|---|---|
| Always quote the delimiter | 'COMMENT' prevents variable and command expansion |
| Use uppercase for delimiters | e.g., 'COMMENT', 'BLOCK', 'NOTE' — improves readability |
| Keep closing marker alone on its line | No spaces or tabs after COMMENT |
Use : <<-"COMMENT" if you want indentation | Great for aligning long documentation |
| Don’t nest here-documents | Bash can’t handle nested blocks safely |
| Avoid in critical production code sections | Only use for inline documentation or testing |
7. Troubleshooting Matrix
| Issue | Cause | Solution |
|---|---|---|
unexpected EOF | End marker missing or mismatched | Make sure start and end names match exactly |
| Variables expanded unexpectedly | Delimiter not quoted | Use : <<'COMMENT' not : <<COMMENT |
| Indented closing marker not recognized | Used spaces instead of tabs | Use tabs only or use unindented form |
| Code inside executes | Forgot the leading : | Always begin with : <<'COMMENT' |
8. Quick Lab
Objective: Add and test multi-line comment blocks in a real WordPress script.
#!/bin/bash
: <<'DOC'
WordPress Plugin Updater
1. Finds wp-config.php in all sites
2. Updates all plugins safely
3. Can disable section using comment blocks
DOC
for c in /home/*/*/public_html/wp-config.php; do
site=$(dirname "$c")
echo "Checking: $site"
# : <<'DISABLE'
# wp plugin update --all --allow-root --path="$site"
# DISABLE
done
Expected Output:
Checking: /home/.../public_html
Checking: /home/.../public_html
Explanation:
The : <<'DOC' and optional : <<'DISABLE' blocks serve as large non-executing documentation sections inside the script.
9. Cheat Sheet
| Purpose | Syntax | Expansion | Use |
|---|---|---|---|
| Literal block comment | : <<'COMMENT' | ❌ No | Documentation / disable code |
| Expandable block | : <<COMMENT | ✅ Yes | Dynamic text notes |
| Indented literal | : <<-"COMMENT" | ❌ No (tabs allowed) | Neat layout with tabs |
| Single-line comment | # text | ❌ No | Short notes only |
10. Glossary
| Term | Definition |
|---|---|
Here-Document (<<) | A redirection method sending multi-line input to a command. |
Null Command (:) | Bash command that does nothing and always succeeds. |
| Quoted Delimiter | 'COMMENT' prevents variable expansion in heredoc. |
Indented Heredoc (<<-"EOF") | Allows leading tabs in block content. |
11. Mini-Quiz
- What command is used with here-documents to ignore content?
- Why should the delimiter be quoted?
- What’s the difference between
<<COMMENTand<<'COMMENT'? - What extra ability does
<<-"COMMENT"provide? - What happens if you forget to close the comment block?
✅ Conclusion The syntax
: <<'COMMENT'
(ignored multi-line content)
COMMENT
is the most reliable and readable way to write multi-line comment blocks in Bash.
Use it for documentation, debugging, or disabling large code sections —
and remember to quote the delimiter ('COMMENT') to prevent any expansion.
Would you like me to continue next with the comparison sheet —
# vs : ' ... ' vs : <<'COMMENT' ... COMMENT' — showing when to use each in Bash scripting?