| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | bash 5.2.26-6.el10 |
| Applies to | Linux distributions with Bash installed |
| Privilege | Normal user for all examples |
| Scope | Covers Bash # comments, inline comments, quoted # characters, multiline-comment alternatives, heredoc caveats, and the difference between comments and shebangs. Also includes a brief note on ShellCheck directives. |
| Related guides | Shell scripting course hub Bash vs sh Bash echo vs printf |
Bash uses # for comments. In normal script syntax, # starts a comment when it appears at the beginning of a line or after unquoted whitespace or an operator. Bash has no native multiline or block-comment syntax, so multiple # lines are the standard approach.
Quick Reference
| Goal | Syntax |
|---|---|
| Full-line comment | # comment |
| Inline comment | command # comment |
Literal # |
"text # text" |
| Multiple lines | Prefix each line with # |
| Heredoc workaround | : <<'COMMENT' … closing COMMENT on its own line |
| Shebang | #!/bin/bash |
Bash Comment Syntax
In Bash, # starts a comment when it begins a word — for example at the start of a line, after unquoted whitespace, or after an operator. Bash ignores the # and everything that follows on that line.
A # inside quotes, or embedded in an existing word such as foo#bar, is treated as ordinary text.
Comments can appear:
- On their own line before or after commands
- After a command on the same line (inline comment)
- Inside a script file saved for later — not only in commands typed at an interactive prompt
Bash also accepts comments at an interactive prompt by default because the interactive_comments option is normally enabled.
Single-Line Comments
Put # at the beginning of a line when you want a full-line note:
#!/bin/bash
# Deploy helper — run after package install
echo "Starting deploy"Save that as deploy.sh and run it with Bash:
bash deploy.shStarting deployBash prints only the echo line. The # line is documentation for humans reading the file.
Inline Comments
You can place # after a command on the same line when # begins a new word. Bash runs the command first, then ignores everything from # to the end of the line:
echo "Hello" # greeting for the userRun it:
bash -c 'echo "Hello" # greeting for the user'HelloThe text after # does not appear in the output because Bash never executes it.
A # embedded in a word does not start a comment:
bash -c 'echo hello#world'hello#worldAdd whitespace before # and the rest of the line is ignored:
bash -c 'echo hello # world'helloKeep inline comments short. A long note at the end of a line is harder to read than a # block above the command.
# Inside Quotes
Inside single or double quotes, # is ordinary text. Bash does not treat it as a comment starter.
Save this as quotes.sh:
#!/bin/bash
echo "# not a comment"
echo 'hash # still literal'Run it:
bash quotes.sh# not a comment
hash # still literalThe first string prints a hash at the start of the line. The second keeps # in the middle of the word hash.
This matters when scripts print prompts, Markdown, or config snippets that contain #. When # needs to appear after whitespace in an argument or string, quote it so Bash treats it as literal text rather than the start of a comment.
How to Comment Multiple Lines in Bash (Block Comments)
Bash has no /* … */ or <!-- … --> block comment syntax. To comment out several lines, use one of these approaches:
- Multiple
#lines — clearest and safest; use this by default - Heredoc no-op workaround —
: <<'DELIMITER' … DELIMITERskips a block; see the next sections for caveats
Use # on each line
# Step 1: verify disk space
# Step 2: copy files to /var/www
# Step 3: reload the service
rsync -a ./site/ /var/www/html/Each line is a normal comment. Editors can toggle these lines with block-comment shortcuts that insert # at the start of each selected row.
Heredoc workaround
Some scripts use a here-document fed to the : built-in (a no-op that always succeeds). Delimiter quoting, expansion rules, and closing-line pitfalls are covered in the Bash heredoc guide—treat this pattern as redirection, not comment syntax:
: <<'COMMENT'
Disabled code or long notes here.
$HOME stays literal when the delimiter is quoted.
COMMENT
echo "active code runs here"Run a minimal example:
bash -c ": <<'COMMENT'
This block is skipped.
COMMENT
echo after block"after blockThe heredoc body is input passed to :; Bash does not execute those lines as shell commands. Execution continues at echo.
Label the delimiter clearly (COMMENT, END, BLOCK) so the closing word is easy to find.
Why a Heredoc Is Not a Real Comment
The heredoc pattern is redirection syntax, not a real Bash comment. That leads to a few important differences.
The body is input, not shell code. The heredoc body is input supplied to the command. It does not have to be valid shell syntax:
: <<'COMMENT'
if this is not valid bash syntax at all !!!
<xml>
some random text
COMMENTWith a quoted delimiter such as <<'COMMENT', the body is also protected from parameter expansion, command substitution, and arithmetic expansion.
Unquoted delimiter — expansions still run. With an unquoted delimiter, Bash still performs parameter expansion, command substitution, and arithmetic expansion inside the here-document. A command substitution such as $(date) is still executed even though its output is discarded with the rest of the heredoc input.
bash -c 'name=Alice
: <<BLOCK
Hello $name
BLOCK
echo done'doneNothing is printed from the block, but $name was still expanded when Bash read the here-document. Quote the delimiter — <<'BLOCK' or <<"BLOCK" — when you want the body treated literally.
Delimiter rules still apply. The closing delimiter must match exactly and, with the << form shown here, must start at the beginning of the line with no extra characters. For ordinary comments or temporarily disabled code, prefix each line with # instead of using a heredoc workaround. Use the heredoc pattern only when you understand its redirection and expansion rules.
Shebang vs Comment
The first line of many scripts looks like a comment:
#!/bin/bashThat line is not a normal Bash comment. When you run ./script.sh, the kernel reads #! and starts the interpreter path that follows. Once Bash is running, it treats the shebang line like a comment and does not execute it as a command.
| Line | Role when running ./script.sh |
Role when running bash script.sh |
|---|---|---|
#!/bin/bash |
Kernel picks the interpreter | Ignored; Bash was started from the command line |
# note |
Bash skips the line | Bash skips the line |
The Bash shebang guide covers #!/bin/bash vs #!/usr/bin/env bash and common shebang errors. The Bash shell script tutorial shows when direct execution uses the shebang and when bash script.sh does not.
ShellCheck Directives Are Special Comments
ShellCheck can read specially formatted comments such as the ones in the ShellCheck and shfmt lint workflow:
# shellcheck disable=SC2034
unused=42Bash ignores the directive like any other comment, but ShellCheck uses it to suppress or configure specific checks.
The source= directive is useful when ShellCheck cannot determine the sourced file path itself. Pair it with the Bash source command when scripts load shared libraries:
# shellcheck source=lib.sh
source lib.shUse directives only when you understand why a warning should be suppressed.
Bash Comment Best Practices
- Prefer full-line
#comments for setup steps, assumptions, and safety notes - Use inline
#only for short clarifications on the same line as a command - Comment why a non-obvious flag or path exists, not what the command name already says
- When temporarily disabling several lines, prefix each line with
#instead of using a heredoc workaround - For line-specific ShellCheck directives, place the directive immediately above the command it affects
Summary
- Bash comments begin with
#when it starts a new word. - Use one
#per line for multiline comments. - A quoted heredoc can be used to skip a block, but it is redirection syntax rather than a real comment.
#!is a shebang when used as the first line of an executable script.
References
- GNU Bash manual — Comments
- GNU Bash manual — Quoting
- GNU Bash manual — Here Documents
- ShellCheck wiki — SC1090 (sourced file paths)
- ShellCheck wiki — SC2034 (unused variables)
Frequently Asked Questions
How do I comment multiple lines in Bash?
Put # at the start of each line you want to skip. Most editors can add or remove # on a selected block. That is safer and clearer than heredoc workarounds for plain documentation.
Can I use /* ... */ for block comments in Bash?
No. Bash does not recognize /* ... */ as comment syntax. The characters are parsed according to normal shell rules, and * may be treated as a filename-matching pattern.
Is #! a comment?
Not in the usual sense. On the first line of an executable script, #! tells the kernel which interpreter to run. After Bash starts, it ignores that line like a comment. A normal # anywhere else is a comment Bash never executes.

