Way to create multiline comments in Bash?

277,906

Solution 1

Use : ' to open and ' to close.

For example:

: '
This is a
very neat comment
in bash
'

Solution 2

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

Solution 3

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.

Solution 4

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.

Solution 5

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

'
Share:
277,906
Admin
Author by

Admin

Updated on July 27, 2022

Comments

  • Admin
    Admin almost 2 years

    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?

  • clt60
    clt60 about 7 years
    :( and also adds a great amount of un-read-ability and potential bug-source. IMHO is better just use multiple #s and never this...
  • Winter
    Winter almost 7 years
    @jm666 IMHO Never a good idea to use the word never when you have no idea of all the use cases.
  • phil294
    phil294 over 6 years
    to explain: : is shorthand for true and true does not process any parameters. (manual page: SYNOPSIS true [ignored command line arguments]
  • becko
    becko about 6 years
    The space between : and ' is important
  • JohnMudd
    JohnMudd about 6 years
    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.
  • Freek
    Freek almost 6 years
    This works, currently accepted answer does not (for me).
  • Thamme Gowda
    Thamme Gowda almost 6 years
    I will just go with : ''' and ''' (three ' as in python)
  • Nux
    Nux almost 6 years
    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.
  • Camille Goudeseune
    Camille Goudeseune almost 6 years
    If you use this to comment out code, and the code has a ', then the comment ends too soon, at that '. Even if it's already in a one-line #-style comment!
  • Thamme Gowda
    Thamme Gowda almost 6 years
    Ah, this one is easy/clean enough to remember!
  • magor
    magor over 5 years
    @Freek need to add space
  • RNA
    RNA over 5 years
    I almost missed the Usage:
  • PyTis
    PyTis over 5 years
    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.
  • PyTis
    PyTis over 5 years
    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. P.S. > This may work according to the syntax highlighting, but fails when running.
  • PyTis
    PyTis over 5 years
    Great addition to the above answer. Honestly, I think you could have edited the above answer, and added this in, instead of answering separately.
  • Infinite Loops
    Infinite Loops over 5 years
    'this is comment in BASH', to make it multiple line, just hit your Enter as long as the sentence ends with ' as well.
  • noamtm
    noamtm over 5 years
    There are a few "above" answers (depending on your sort order). And, by answering separately I wanted to explain the rationale behind the string I chose.
  • Imre
    Imre over 5 years
    hello, wasn't intended as a question, rather than an answer to the original question
  • Nathan
    Nathan over 5 years
    @Freek did mazs' comment help? I'm wondering why it doesn't work for you
  • Freek
    Freek over 5 years
    It's been a while, I could well have been that space indeed.
  • Perl Ancar
    Perl Ancar over 5 years
    @PyTis couldn't reproduce it. I pasted the above code to a shell script and it worked. Perhaps if you could share the error message you got.
  • Perl Ancar
    Perl Ancar over 5 years
    @t.y couldn't agree more. Although it's a few characters more, the END_COMMENT tokens (or something alike) makes it much clearer that the block between is a comment. plus this is not messed up as easily by one single quote. I do it sometimes in Perl too, although with a decent text editor it's not much hassle to just add # to each line in a selection. (M-x comment-region in emacs).
  • Perl Ancar
    Perl Ancar over 5 years
    As the previous answer notes, aside from backquotes, $(...) sequence will also be expanded as both forms are command substitution.
  • Perl Ancar
    Perl Ancar over 5 years
    "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.
  • Perl Ancar
    Perl Ancar over 5 years
    @ThammeGowda nice, but it doesn't work exactly like in Python. A single ' inside the "comment" will still break things.
  • Perl Ancar
    Perl Ancar over 5 years
    In general I'd recommend the heredoc (quoted variant) because it's clearer and does not break so easily.
  • Oliver
    Oliver over 5 years
    @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).
  • Oliver
    Oliver over 5 years
    @PyTis bear in mind that votes can change the relative order of answers so "the one below" may become wrong. Better use "answer by @name" (can't remember if the mention gets converted internally to user ID - I think it does - if not and author changes their name in their settings then such mentions become dangling... only sure way is a URL to the answer).
  • wisbucky
    wisbucky almost 5 years
    Good tests in your example. The leading : is not necessary. Just start with <<.
  • Ferris
    Ferris over 4 years
    << EOF ... EOF
  • user1934428
    user1934428 almost 4 years
    @Oliver : If unquoted, variables can have nasty side effects. Imagine that you have embedded in your heredoc-comment a string such as ${FOO:=bar} or ${FOO{}}. The first may have the side effect to create and set the variable FOO, the second will raise a bad substitution error; both effects you would not expect from a real comment.
  • Oliver
    Oliver almost 4 years
    @user1934428 and @ perlancar the single quote version does not support substitutions
  • user1934428
    user1934428 almost 4 years
    @Oliver : Yes, and this is a good thing: We don't want substitutions. But you wrote _ Even with set -o verbose and $variables mentioned in the comment, quoting the marker is not necessary_, and this is not correct: If you don't (single-)quote the heredoc marker, you do have substitutions in your heredoc.
  • user1934428
    user1934428 almost 4 years
    Because of course you don't create an enviroment variable in that way (I never said so), but just a variable. You have to do a echo $FOO to see the effect.
  • user1934428
    user1934428 almost 4 years
    Not good IMO. It requires the comment to be parsable as shell code, which is pretty restrictive.
  • user1934428
    user1934428 almost 4 years
    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.
  • Oliver
    Oliver almost 4 years
    @user1934428 well I didn't think so but you said "The first may have the side effect to create and set the variable". Anyways I've substantially updated the post.
  • user1934428
    user1934428 almost 4 years
    @Oliver: Great. It is important to observe the difference between variables and environment variables (i.e. exported variables). The latter is not so easy to accidentally create.
  • RonJohn
    RonJohn about 3 years
    "wasn't intended as a question" Then don't ask a question.
  • grantiago
    grantiago about 3 years
    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.
  • yurenchen
    yurenchen over 2 years
    ' is not safe in this "comment" block
  • yurenchen
    yurenchen over 2 years
    << '////' is safe than << ////
  • yurenchen
    yurenchen over 2 years
    } maybe not safe
  • fali
    fali over 2 years
    I tried this and got: Invalid null command. didn't run the code after the blocked code.
  • logidelic
    logidelic about 2 years
    Not safe and broke unexpectedly for me. Agree with others who say that HEREDOC answer is better.
  • Sohail Si
    Sohail Si about 2 years
    I wish syntax highlight mechanism in stackoverflow could detect (and colour highlight) this correctly
  • Sohail Si
    Sohail Si about 2 years
    A major benefit to all other solutions is that most of current syntax highlight tools (for bash syntax) can recognise an unclosed single quote ' . We are in need of syntax highlight libraries for more accurate colourising of bash syntax.
  • noamtm
    noamtm about 2 years
    @SohailSi ¯\ _(ツ)_/¯ - it's a hack. I'm sure if it was an actual feature of bash it would be supported.