333

Is there a simple way to comment out a block of code in a shell script?

Asclepius
  • 57,944
  • 17
  • 167
  • 143
theycallmemorty
  • 12,515
  • 14
  • 51
  • 71
  • 5
    Interesting how such easy and simple question has too different and complicated answers. – Sigur Nov 28 '16 at 21:28

15 Answers15

430

In bash:

#!/bin/bash
echo before comment
: <<'END'
bla bla
blurfl
END
echo after comment

The ' and ' around the END delimiter are important, otherwise things inside the block like for example $(command) will be parsed and executed.

For an explanation, see this and this question.

Asclepius
  • 57,944
  • 17
  • 167
  • 143
sunny256
  • 9,246
  • 2
  • 25
  • 22
  • 31
    Cute trick - as long as the 'END' keyword (which is, of course, user chosen) does not appear on a line on its own inside the material to be commented out. – Jonathan Leffler Jun 04 '09 at 00:47
  • Very nice trick. BTW, This should work in any Bourne compatible shell as well. – Michał Šrajer Apr 19 '11 at 08:43
  • @JonathanLeffler what do you mean by "which is, of course, user chosen"? That I can use any string I choose in place of END? – KalenGi Jun 28 '12 at 02:11
  • 13
    @kalengi: Yes; the word used in the quotes can be anything convenient; `EOF` is a classic example (and so is `!`, an exclamation mark on its own), but you could use `SNURFLE_BURGERS` or `classical_end_marker` or any other word that doesn't appear on a line on its own in the commented-out material. I'd be leary of experimenting with spaces etc, but the word might well work with them too. – Jonathan Leffler Jun 28 '12 at 18:34
  • 2
    (Works if one removes the single quotes, however.) – Hot Licks Jul 10 '12 at 17:22
  • 1
    Interestingly enough, Emacs on mac actually recognizes `echo before comment : < – Chris Marie May 07 '14 at 19:57
  • 4
    It definitely works but can anyone elaborate on how this works? Thanks – mbbce May 14 '15 at 08:00
  • 5
    @MB_CE, see http://stackoverflow.com/questions/32126653/how-does-end-work-in-bash-to-create-a-multi-line-comment-block#32126942. That said -- it's running a command (`:`) that doesn't read its input and always exits with a successful value, and sending the "comment" as input. Not much to it. – Charles Duffy Aug 20 '15 at 19:57
  • 1
    @HotLicks, generally, "shell script" these days refers to POSIX sh derivatives. csh isn't one, so only answers to questions specifically tagged csh can be expected to work with it. – Charles Duffy Aug 20 '15 at 19:58
  • 1
    @JonathanLeffler, "SNURFLE_BURGERS"? I saw somebody else use that same string in another thread on commenting shell scripts. Is there a story behind that? – Duncan C Dec 16 '15 at 17:49
  • @DuncanC: I have no recollection of why or how I came up with "snurfle burgers" in that comment. AFAICR, I have not used the term before or since. – Jonathan Leffler Dec 16 '15 at 17:55
  • 2
    You're famous: http://codextechnicanum.blogspot.com/2013/11/comment-out-block-of-code-in-bash-shell.html – Duncan C Dec 16 '15 at 18:34
  • 3
    I consider it incredibly ugly and confusing to write active code to create passive code... just use good old block select mode and press #; what's the big issue with that? – Rusty75 Feb 27 '17 at 15:37
  • thanks for the tip with the quotes. I was pulling my hair wondering why the commands inside the "commented" section still executed! – verboze Jun 30 '17 at 16:48
  • 1
    Complex answer to a simple question. Best answer would be # before any line – Stathis Andronikos Dec 08 '17 at 13:14
  • 1
    I found a script that does basically that, but without the `:` (that is just `<<'EOF' ... ... .. EOF` and it seems to work as well. I don't understand why. – René Nyffenegger Mar 07 '18 at 11:55
  • @Rusty75 it is sometimes your only choice if you are dealing with programs you cannot completely control. example is an isql client for sybase IQ which cannot suppress (N rows affected) message. If you need sql query to produce bash code then you can make sure your SELECT output begins with close comment and ends with open comment... – spioter Sep 21 '19 at 13:18
  • 1
    This has the advantage that in an editor which color-highlights here-docs (I use jEdit, I assume other editors do the same thing) the "commented" block is colored differently from "normal" code. – Bob Jarvis - Слава Україні Aug 13 '20 at 18:00
  • Great! I've been using the if [[ 1 -eq 0 ]] until now, but this is much better. Thanks! – Eran Ben-Natan Dec 29 '20 at 20:48
109

Use : ' to open and ' to close.

For example:

: '
This is a
very neat comment
in bash
'

This is from Vegas's example found here

Relative0
  • 1,567
  • 4
  • 17
  • 23
109

There is no block comment on shell script.

Using vi (yes, vi) you can easily comment from line n to m

<ESC>
:10,100s/^/#/

(that reads, from line 10 to 100 substitute line start (^) with a # sign.)

and un comment with

<ESC>
:10,100s/^#//

(that reads, from line 10 to 100 substitute line start (^) followed by # with noting //.)

vi is almost universal anywhere where there is /bin/sh.

Jens
  • 69,818
  • 15
  • 125
  • 179
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 1
    Nice trick with regular expression on vi to place # in front of lines. – Atiq Rahman Mar 07 '13 at 09:34
  • 7
    Just a tip - if you're using vim and this ends up highlighting the beginning of every line, add `|noh` to the end. The pipe separates additional commands and `noh` is for nohighlight. Search term highlighting will automatically resume the next time you search for something. Example: `:10,100s/^/#/g|noh` – Matthew Mar 13 '15 at 20:43
  • I need this to be automated from a script. Is there a way to do that to a file with vi without needing human interaction? – Timothy Swan Mar 05 '18 at 21:12
  • 1
    @TimothySwan I imagine the gawk or sed program could do that... somehow. – BeowulfNode42 Apr 18 '18 at 04:07
  • 1
    my preferred way of commenting (or prefixing) a block with vi: go to beginning of the line you want to start commenting (e.g. `+G 10 ` then `0` or by any other way to navigate). Then use `+V` to enter visual block mode and highlight the beginning of all lines you want to comment (in this example `90 J`). Then press `SHIFT+I` to insert before the highlighted block. Enter the comment sign (e.g. `#`) and press `` to finish your prefixing. This explanation sounds super long, but in my experience it is much faster in practice. – Ueffes Nov 08 '19 at 13:47
62

You can use:

if [ 1 -eq 0 ]; then
  echo "The code that you want commented out goes here."
  echo "This echo statement will not be called."
fi
Jean
  • 7,623
  • 6
  • 43
  • 58
dannyhan12
  • 942
  • 8
  • 9
32

The following should work for sh,bash, ksh and zsh.

The blocks of code to be commented can be put inside BEGINCOMMENT and ENDCOMMENT:

[ -z $BASH ] || shopt -s expand_aliases
alias BEGINCOMMENT="if [ ]; then"
alias ENDCOMMENT="fi"

BEGINCOMMENT
  echo "This line appears in a commented block"
  echo "And this one too!"
ENDCOMMENT

echo "This is outside the commented block"

Executing the above code would result in:

This is outside the commented block

In order to uncomment the code blocks thus commented, say

alias BEGINCOMMENT="if : ; then"

instead of

alias BEGINCOMMENT="if [ ]; then"

in the example above.

devnull
  • 118,548
  • 33
  • 236
  • 227
30

if you can dodge the single quotes:

__='
blah blah comment.
'
vanvliet.eric
  • 401
  • 4
  • 3
  • I like this. What does the double underscore mean though? As best as I can tell it's just a variable name using the convention that it should be treated as private? – chessofnerd Jul 28 '15 at 01:27
  • Also provides syntax highlighting in most editors and is callable if needed with $__ though I would suggest a variable name like documentation or docs for clarity. – jasonleonhard Jan 17 '18 at 00:08
  • You can also append the word local in front [ref here](http://tldp.org/LDP/abs/html/localvar.html) – jasonleonhard Jan 17 '18 at 00:10
  • This should be the best answer. Just put some dummy variable name instead of the double underscores – B Abali Nov 11 '18 at 21:31
  • 1
    Tried this, but failed because there was a -F';' inside of the block to comment out. – yO_ Mar 01 '19 at 08:33
15

In Vim:

  1. go to first line of block you want to comment
  2. shift-V (enter visual mode), up down highlight lines in block
  3. execute the following on selection :s/^/#/
  4. the command will look like this:

      :'<,'>s/^/#
    
  5. hit enter

e.g.

shift-V
jjj
:s/^/#
<enter>
stefanB
  • 77,323
  • 27
  • 116
  • 141
4

You could use Vi/Vim's Visual Block mode which is designed for stuff like this:

Ctrl-V  
Highlight first element in rows you want commented  
Shift-i  
#  
esc  

Uncomment would be:

Ctrl-V  
Highlight #'s  
d  
l  

This is vi's interactive way of doing this sort of thing rather than counting or reading line numbers.

Lastly, in Gvim you use ctrl-q to get into Visual Block mode rather than ctrl-v (because that's the shortcut for paste).

horta
  • 1,110
  • 8
  • 17
4

In all honesty, why so much overengineering...

I consider it really a bad practice to write active code for generating passive code.

My solution: most editors have block select mode. Just use it to add # to all lines you want to comment out. What's the big deal...

Notepad example:

To create: Alt - mousedrag down, press #.

To delete: Alt-mousedrag down, shift-right arrow, delete.

Rusty75
  • 477
  • 7
  • 19
  • 11
    User most likely is in terminal. Cannot assume a mouse environment. – Gary Apr 18 '18 at 00:19
  • Do they still exist? I usually edit in graphical mode and paste back in using vi, that would be an easy workaround. – Rusty75 May 30 '18 at 08:13
3

You can put the code to comment inside a function. A good thing about this is you can "uncomment" by calling the function just after the definition.

Unless you plan to "uncomment" by calling the function, the text inside the function does not have to be syntactically correct.

ignored() {
  echo this is  comment
  echo another line of comment
}

Many GUI editors will allow you to select a block of text, and press "{" to automatically put braces around the selected block of code.

Ari Singh
  • 1,228
  • 7
  • 12
2

A variation on the here-doc trick in the accepted answer by sunny256 is to use the Perl keywords for comments. If your comments are actually some sort of documentation, you can then start using the Perl syntax inside the commented block, which allows you to print it out nicely formatted, convert it to a man-page, etc.

As far as the shell is concerned, you only need to replace 'END' with '=cut'.

echo "before comment"
: <<'=cut'
=pod

=head1 NAME
   podtest.sh - Example shell script with embedded POD documentation

etc.

=cut
echo "after comment"

(Found on "Embedding documentation in shell script")

mivk
  • 13,452
  • 5
  • 76
  • 69
2

I like a single line open and close:

if [ ]; then ##
    ...
    ...
fi; ##

The '##' helps me easily find the start and end to the block comment. I can stick a number after the '##' if I've got a bunch of them. To turn off the comment, I just stick a '1' in the '[ ]'. I also avoid some issues I've had with single-quotes in the commented block.

Ynnub
  • 21
  • 1
1

Let's combine the best of all of these ideas and suggestions.

alias _CommentBegin_=": <<'_CommentEnd_'"

as has been said, the single quote is very important, in that without them $(commandName) and ${varName} would get evaluated.

You would use it as:

_CommentBegin_
echo "bash code"
or 
none code can be in here
_CommentEnd_

The alias makes the usage more obvious and better looking.

Mohsen Banan
  • 85
  • 1
  • 5
0

This can be done in a shorter syntax in sh, bash and ksh

<< COMMENT

They worked in the cold, so we could be warm,
some died in the evening, some died at dawn.
They breathed in the coal dust, so kids would be fed,
Gone are those miners, all of them dead.


COMMENT
access_granted
  • 1,807
  • 20
  • 25
-1

Another mode is: If your editor HAS NO BLOCK comment option,

  1. Open a second instance of the editor (for example File=>New File...)
  2. From THE PREVIOUS file you are working on, select ONLY THE PART YOU WANT COMMENT
  3. Copy and paste it in the window of the new temporary file...
  4. Open the Edit menu, select REPLACE and input as string to be replaced '\n'
  5. input as replace string: '\n#'
  6. press the button 'replace ALL'

DONE

it WORKS with ANY editor