500

I have recently started studying shell script and I'd like to be able to comment out a set of lines in a shell script. I mean like it is in case of C/Java :

/* comment1
   comment2 
   comment3
*/

How could I do that?

4
  • 2
    You can use hash like : #this is a comment. Commented Apr 1, 2017 at 15:17
  • 3
    I know but it's a little troublesome for multiline. Commented Apr 1, 2017 at 19:28
  • 3
    It should be noted that the below answers require that the : be in the first column (no leading spaces) in the line. Commented Feb 1, 2018 at 1:43
  • Does this answer your question? Block Comments in a Shell Script Commented Dec 2, 2023 at 14:16

16 Answers 16

891

Use : ' to open and ' to close.

For example:

: '
This is a
very neat comment
in bash
'

Paul tried to summarize all the numerous comments,
which gave the updated 2026 answer aka CSA-HSA.

Sign up to request clarification or add additional context in comments.

:( and also adds a great amount of un-read-ability and potential bug-source. IMHO is better just use multiple #s and never this...
Not quite sure what you are talking about - using multiple #s can make a block comment difficult to format (so it won't be) and more difficult to edit. I don't see any "potential bug-source" other than embedding an apostrophe in the comment, which is easy to find when bash complains; its not something that will pop up years down the road. Everyone I show this method to thinks it is great.
@jm666 IMHO Never a good idea to use the word never when you have no idea of all the use cases.
to explain: : is shorthand for true and true does not process any parameters. (manual page: SYNOPSIS true [ignored command line arguments]
The space between : and ' is important
I modified this slightly for blocks of code so I can easily switch the code either on or off. My change is to use # ' on the last line instead of the single quote. This way I can put a single # on the first line to activate the block of code. Remove the # on first line to deactivate the code.
240

Multiline comment in bash

: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines.  Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2 
comment3
END_COMMENT

It's probably worth noting that this is not a comment per se. This is a heredoc that is redirected to NOP command as a multi-line string. Single quote is important to disable resolving variables and commands.
@Freek need to add space
I tested this in a simple bash script that runs via it's shebang line, #!/bin/bash in Debian and it failed. I'm trying each answer on this page, and they've all failed until I got to the one below. Since they failed, I am down-voting them, and up-voting the one that actually runs properly.
'this is comment in BASH', to make it multiple line, just hit your Enter as long as the sentence ends with ' as well.
Good tests in your example. The leading : is not necessary. Just start with <<.
90

Note: I updated this answer based on comments and other answers, so comments prior to May 22nd 2020 may no longer apply. Also I noticed today that some IDE's like VS Code and PyCharm do not recognize a HEREDOC marker that contains spaces, whereas bash has no problem with it, so I'm updating this answer again.

Bash does not provide a builtin syntax for multi-line comment but there are hacks using existing bash syntax that "happen to work now".

Personally I think the simplest (ie least noisy, least weird, easiest to type, most explicit) is to use a quoted HEREDOC, but make it obvious what you are doing, and use the same HEREDOC marker everywhere:

<<'###BLOCK-COMMENT'
line 1
line 2

line 3
line 4
###BLOCK-COMMENT

Single-quoting the HEREDOC marker avoids some shell parsing side-effects, such as weird subsitutions that would cause crash or output, and even parsing of the marker itself. So the single-quotes give you more freedom on the open-close comment marker.

For example the following uses a triple hash which kind of suggests multi-line comment in bash. This would crash the script if the single quotes were absent. Even if you remove ###, the FOO{} would crash the script (or cause bad substitution to be printed if no set -e) if it weren't for the single quotes:

set -e

<<'###BLOCK-COMMENT'
something something ${FOO{}} something
more comment
###BLOCK-COMMENT

ls

You could of course just use

set -e

<<'###'
something something ${FOO{}} something
more comment
###

ls

but the intent of this is definitely less clear to a reader unfamiliar with this trickery.

Note my original answer used '### BLOCK COMMENT', which is fine if you use vanilla vi/vim but today I noticed that PyCharm and VS Code don't recognize the closing marker if it has spaces.

Nowadays any good editor allows you to press ctrl-/ or similar, to un/comment the selection. Everyone definitely understands this:

# something something ${FOO{}} something
# more comment
# yet another line of comment

although admittedly, this is not nearly as convenient as the block comment above if you want to re-fill your paragraphs.

There are surely other techniques, but there doesn't seem to be a "conventional" way to do it. It would be nice if ###> and ###< could be added to bash to indicate start and end of comment block, seems like it could be pretty straightforward.

Ah, this one is easy/clean enough to remember!
As the previous answer notes, aside from backquotes, $(...) sequence will also be expanded as both forms are command substitution.
"Both are hacks so they could break scripts in the future." Could you expand on this? Although hacks semantically, syntactically they are valid and should not break in the future, unless bash decides to go berserk and breaks heredocs.
@perlancar If we agree that hacks are solutions that use a language / lib feature that is completely unrelated to the problem (like using a heredoc for a comment, or using a parameter on a do-nothing command like true), then even if they don't risk breaking (heredoc approach doesn't, but colon version does), 1) hacks still obfuscate the intent: without the first line hinting about multiline comment, most would scratch their head wondering what that code is doing; and 2) have unexpected dark corners (like having to double a quote, quote the heredoc marker in certain cases, etc).
In all of this great info and discussion -- Nowadays any good editor allows you to press ctrl-/ or similar, to un/comment the selection. In my case: ctrl Q. Sadly, I never figured this out for myself.
52

After reading the other answers here I came up with the below, which IMHO makes it really clear it's a comment. Especially suitable for in-script usage info:

<< ////

Usage:
This script launches a spaceship to the moon. It's doing so by 
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.

////

As a programmer, the sequence of slashes immediately registers in my brain as a comment (even though slashes are normally used for line comments).

Of course, "////" is just a string; the number of slashes in the prefix and the suffix must be equal.

I almost missed the Usage:
<< EOF ... EOF
<< '////' is safe than << ////
@julaine the << part opens a "heredoc" (en.wikipedia.org/wiki/Here_document). The four slashes are the terminating string of the heredoc (the first time defines them as the terminating string, the second time just terminates).
@noamtm thank you, that makes sense. I thought there would be some significance to the Usage:-part
11

In plain bash, to comment out a block of code, I do:

:||{
block
of code
}

Clever - true || ____
Best one I've seen so far. Nice.
9

Here Documents

<<EOF & EOF solution

#!/usr/bin/env bash

echo "just use the \`EOF\` for multi-line comments in your shell script. 🚀"

<<EOF
  comment1
  comment2 
  comment3
  # ...
EOF

By the way: you can also rename EOF to other unique name, such SHELL_MULTI_LINE_COMMENTS.

#!/usr/bin/env bash

echo "just use the \`SHELL_MULTI_LINE_COMMENTS\` for multi-line comments in your shell script. 🚀"

<<SHELL_MULTI_LINE_COMMENTS
  comment1
  comment2 
  comment3
  # ...
SHELL_MULTI_LINE_COMMENTS

test ✅


#!/usr/bin/env bash

echo "just use the \`EOF\` for multi-line comments in your shell script. 🚀"

<<EOF
  comment1
  comment2
  comment3
  # ...
EOF

echo "just use the \`SHELL_MULTI_LINE_COMMENTS\` for multi-line comments in your shell script. 🚀"

<<SHELL_MULTI_LINE_COMMENTS
  comment1
  comment2
  comment3
  # ...
SHELL_MULTI_LINE_COMMENTS

$ chmod +x ./multi-line-comments.sh

$ ./multi-line-comments.sh
just use the `EOF` for multi-line comments in your shell script. 🚀
just use the `SHELL_MULTI_LINE_COMMENTS` for multi-line comments in your shell script. 🚀

screenshots

enter image description here

fefs

https://en.wikipedia.org/wiki/Here_document

https://tldp.org/LDP/abs/html/here-docs.html

What text editor are you using for that Screenshot?
Better, you add quotes to the Heredoc marker to avoid variable substitutions because otherwise arbitrary code execution is possible, careful! <<"EOF"␤The first thing taught to learners usually is to not just trust and execute code from the Internet such as $(rm -rf ~).␤EOF
8

I tried the chosen answer, but found when I ran a shell script having it, the whole thing was getting printed to screen (similar to how jupyter notebooks print out everything in '''xx''' quotes) and there was an error message at end. It wasn't doing anything, but: scary. Then I realised while editing it that single-quotes can span multiple lines. So.. lets just assign the block to a variable.

x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"

ls -l
date

'

Just no need to assign it to a variable, which is a side effect we would not expect from a 'comment'. Replace the x= by a : and you have the same effect with no side effect. The only drawback is that the comment then must not contain a single quote. That's why I prefer the usage of a quoted heredoc: With this, the commenter can choose a suitable termination string as he likes.
7

what's your opinion on this one?

function giveitauniquename()
{
  so this is a comment
  echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
  the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
  only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
  1, for #((
  2, this #wouldn't work either
  function giveitadifferentuniquename()
  {
    echo nestable
  }
}

hello, wasn't intended as a question, rather than an answer to the original question
Not good IMO. It requires the comment to be parsable as shell code, which is pretty restrictive.
"wasn't intended as a question" Then don't ask a question.
} maybe not safe
7

Simple solution, not much smart:

Temporarily block a part of a script:

if false; then
    while you respect syntax a bit, please
    do write here (almost) whatever you want.
    but when you are
    done # write
fi

A bit sophisticated version:

time_of_debug=false # Let's set this variable at the beginning of a script

if $time_of_debug; then # in a middle of the script  
    echo I keep this code aside until there is the time of debug!
fi

Comments

5

Here's how I do multiline comments in bash.

This mechanism has two advantages that I appreciate. One is that comments can be nested. The other is that blocks can be enabled by simply commenting out the initiating line.

#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A

In the example above the "B" block is commented out, but the parts of the "A" block that are not the "B" block are not commented out.

Running that example will produce this output:

foo {
./example: line 5: fn: command not found
foo }
can't happen

Comments

4

After read all solutions prior to 2023.03.25, I use this solution. The benefit of it:

  1. Support nested comment.
  2. Support comment out some multi-line comment by prefix with #
  3. Readable.
  4. Allow single quote in comment.
  5. Pass shellcheck

The cons:

  1. The last command exit code will be reset as zero before comment.
  2. vim color syntax still can not detect it correctly.
  3. longer(but readable).

Here is the example of "disable COMMENT1" and "enable COMMENT2".

#!/bin/bash

echo "line 1"
#: <<'#END_COMMENT1'
echo "line 2"
echo "line 3"
false
: <<'#END_COMMENT2'
echo "line 4"
echo "line 5"
#END_COMMENT2
echo "status code=$?"
#END_COMMENT1
echo "line 6"

output

line 1
line 2
line 3
status code=0
line 6

If you care about the exit code side effect, use the single line comment like

echo "line 1"
echo "line 2"
echo "line 3"
false
#echo "line 4"
#echo "line 5"
echo "status code=$?"
echo "line 6"

output

line 1
line 2
line 3
status code=1
line 6

Comments

2

This is perhaps a bit of a non-answer, but the idiomatic way to handle multiline comments in Bash is to comment each line individually with the comment character #. For example:

# This is a multiline comment
# 
# It spans multiple lines, but each line 
# has its own comment character.

Any modern text editor will support selecting multiple lines at once and commenting them all out with a keyboard shortcut, and a good text editor will support reflowing the text automatically (for example, in emacs, this can be done with M-q).

It's best to use the idiomatic method with normal comment characters. It is what people will expect to see, it will avoid bugs, and text editors will actually syntax highlight the text as a comment (notice how the above example is colored gray by StackOverflow's Markdown, because it's actually colored as a comment).

Comments

1

Not even if you use the inner apostrophe, this method does not allow the following content:

: '
' => &#39;
(') => &#39;
'

The best is the shortest:

<</
' => &#39;
(') => &#39;
\/ or #/
/

Comments

1

I'm surprised no one else has come up with this one:

<<```
echo This is commented out!
echo $(echo This does not trigger | tee /dev/tty)
```
echo This fires

I have no earthly clue why this works considering ` is the old "command substitution" syntax. I double-checked and there's no command substitution happening whatsoever.

Comments

1

TLDR : '&# ' aka CSA-HSA
( See also Block Comments in a Shell Script )
Use : ' to open and line-ending ' to close.


Or even better use : ' to open and # ' to close.
So key combination like Cmd + / in an Editor on the single first line will enable/disable code block.

This makes pair of #: '+# ' a nice visible and easily to disable, i.e. optional code,
aka CSA-HSA optional blocks:

#: ' CSA-HSA optional blocks
# 8. (Optional) Verify that docker and docker-compose is fully installed and functional
echo "Verifying installation..."
docker --version
docker compose version
#docker run --rm hello-world
# '

Note that space between : and ' is important !

For example:

: '
[hash-]colon-space-apostrophe
echo
This is
stackoverflow.com most"s loved way
to block-comments
to disable lines of code
in bash
as of April 2026

with final # added
So adding single # on the first line re-activates the block of code, 
and removing the # on first line re-deactivates it.
So #: " marks an easy-to-disable or a re-enabled (i.e. optional) block of code!
up to this magic CSA-HSA ending 
hash-space-apostrophe
# '

Explanation: : is shorthand for true and true does not process any parameters.
Other 2021 answer suggested similar elegant, "evil"-looking, but without need of likely forgotten space character as true || ____:

:||{
block
of code
}

See also https://unix.stackexchange.com/a/61546

Note for potential problems:

  1. These multi-line strings MUST NOT have a string-ending ' within
    (or similarly } if you used :||{+}) .
  2. Markdown coloring will stop at any ' within.
  3. Most Editors (e.g. IDEA) coloring will stop at any ' within.
    Not as bad, if you those ' go in pairs, i.e. even number of them.
  4. shellcheck will flag, if the comment includes backticks (`).

Used resources:

This answer is as-of-20026 summary of all the comments to the most loved and commented Vegas answer and other comments in SO answer).
The idea of using final # was [comment by @JohnMudd ][https://stackoverflow.com/questions/43158140/way-to-create-multiline-comments-in-bash/43158193#comment86913329_43158193]

I modified this slightly for blocks of code so I can easily switch the code either on or off. My change is to use # ' on the last line instead of the single quote. This way I can put a single # on the first line to activate the block of code. Remove the # on first line to deactivate the code.

:||{ The human history may wish that @JohnMudd has had added own new Stackoverflow answer, then this whole solution would have be known as @JohnMudd-way instead of CSA-HSA. But C'est la vie aka The ways of the Lord are invisible.}

Comments

0

The lovely apostrophe to the rescue! For example, in awesome Bash v5.2.37:

# Get a file from an HTTPS server that requires user and password.
echo curl `
    # The server, apparently, requires Basic Auth...
    `-u \
        'web'`        # User
        `':'`         # Delimiter
        `'356a192b' ` # Password

    # cURL supports various proxy protocols, including HTTP and SOCKS!
    `-x 'example.com:8080' `

    # Since the proxy requires authentication,
    # let's set it!
    `-U \
        'proxy'`     # User
        `':'`        # Delimiter!
        `'7913b04c'` # Password` \
    -- 'https://example.com/';
curl -u web:356a192b -x example.com:8080 -U proxy:7913b04c -- https://example.com/

At voila!

Comments

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.