Multiline shell script comments - how does this work?

That is not a multi-line comment. # is a single line comment. : (colon) is not a comment at all, but rather a shell built-in command that is basically a NOP, a null operation that does nothing except return true, like true (and thus setting $? to 0 as a side effect). However since it is a command, it can accept arguments, and since it ignores its arguments, in most cases it superficially acts like a comment. The main problem with this kludge is the arguments are still expanded, leading to a host of unintended consequences. The arguments are still affected by syntax errors, redirections are still performed so : > file will truncate file, and : $(dangerous command) substitutions will still run.

The least surprising completely safe way to insert comments in shell scripts is with #. Stick to that even for multi-line comments. Never attempt to (ab)use : for comments. There is no dedicated multi-line comment mechanism in shell that is analogous to the slash-star /* */ form in C-like languages.


For the sake of completeness, but not because it is recommended practice, I will mention that it is possible to use here-documents to do multi-line "comments":

: <<'end_long_comment'
This is an abuse of the null command ':' and the here-document syntax
to achieve a "multi-line comment".  According to the POSIX spec linked 
above, if any character in the delimiter word ("end_long_comment" in 
this case) above is quoted, the here-document will not be expanded in 
any way.  This is **critical**, as failing to quote the "end_long_comment" 
will result in the problems with unintended expansions described above. 
All of this text in this here-doc goes to the standard input of :, which 
does nothing with it, hence the effect is like a comment.  There is very 
little point to doing this besides throwing people off.  Just use '#'.
end_long_comment

It's not any style of commenting. the : built-in command does absolutely nothing; it's being abused for commenting here.

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

In early shells, the colon was the only way to create comments.

However, it is not a true comment, because the line is parsed in exactly the same way as any other command is parsed, and that may have side effects. For example:

: ${a:=x} # assigns the value 'x' to the variable, 'a'

: $(command) # executes 'command'

(Sometimes the colon is use solely for the purpose of invoking those side effects, but then it’s not being used as a comment.)

It is sometimes convenient to use the colon to comment out a section of a script:

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'

This is a great timesaver over preceding each line with #, particularly if the commenting out is only temporary.