I've been writing some batch files, and I ran into this user guide, which has been quite informative. One thing it showed me was that lines can be commented not just with REM
, but also with ::
. It says:
Comments in batch code can be made by using a double-colon, this is better than using the REM command because labels are processed before redirection symbols.
::<remark>
causes no problems butrem <remark>
produces errors.
Why then, do most guides and examples I see use the REM
command? Does ::
work on all versions of Windows?
James K, I'm sorry I was wrong in a fair portion of what I said. The test I did was the following:
This meets your description of alternating but fails with a ") was unexpected at this time." error message.
I did some farther testing today and found that alternating isn't the key but it appears the key is having an even number of lines, not having any two lines in a row starting with double colons (::) and not ending in double colons. Consider the following:
This works!
But also consider this:
The rule of having an even number of comments doesn't seems to apply when ending in a command.
Unfortunately this is just squirrelly enough that I'm not sure I want to use it.
Really, the best solution, and the safest that I can think of, is if a program like Notepad++ would read REM as double colons and then would write double colons back as REM statements when the file is saved. But I'm not aware of such a program and I'm not aware of any plugins for Notepad++ that does that either.
Comments with REM
A
REM
can remark a complete line, also a multiline caret at the line end, if it's not the end of the first token.REM followed by some characters
.:\/=
works a bit different, it doesn't comment an ampersand, so you can use it as inline comment.But to avoid problems with existing files like
REM
,REM.bat
orREM;.bat
only a modified variant should be used.And for the character
;
is also allowed one of;,:\/=
REM is about 6 times slower than
::
(tested on Win7SP1 with 100000 comment lines).For a normal usage it's not important (58µs versus 360µs per comment line)
Comments with ::
A
::
always executes a line end caret.Labels and also the comment label
::
have a special logic in parenthesis blocks.They span always two lines SO: goto command not working.
So they are not recommended for parenthesis blocks, as they are often the cause for syntax errors.
With
ECHO ON
aREM
line is shown, but not a line commented with::
Both can't really comment out the rest of the line, so a simple
%~
will cause a syntax error.But REM is able to stop the batch parser at an early phase, even before the special character phase is done.
You can use &REM or &:: to add a comment to the end of command line. This approach works because '&' introduces a new command on the same line.
Comments with percent signs %= comment =%
There exists a comment style with percent signs.
In reality these are variables but they are expanded to nothing.
But the advantage is that they can be placed in the same line, even without
&
.The equal sign ensures, that such a variable can't exists.
The percent style is recommended for batch macros, as it doesn't change the runtime behaviour, as the comment will be removed when the macro is defined.
This answer attempts a pragmatic summary of the many great answers on this page:
jeb's great answer deserves special mention, because it really goes in-depth and covers many edge cases.
Notably, he points out that a misconstructed variable/parameter reference such as
%~
can break any of the solutions below - includingREM
lines.Whole-line comments - the only directly supported style:
REM
(or case variations thereof) is the only official comment construct, and is the safest choice - see Joey's helpful answer.::
is a (widely used) hack, which has pros and cons:Pros:
Cons:
(...)
blocks,::
can break the command, and the rules for safe use are restrictive and not easy to remember - see below.If you do want to use
::
, you have these choices:(...)
blocks and useREM
there, or do not place comments inside(...)
altogether.::
inside(...)
, which are summarized in the following snippet:Emulation of other comment styles - inline and multi-line:
Note that none of these styles are directly supported by the batch language, but can be emulated.
Inline comments:
* The code snippets below use
ver
as a stand-in for an arbitrary command, so as to facilitate experimentation.* To make
SET
commands work correctly with inline comments, double-quote thename=value
part; e.g.,SET "foo=bar"
.[1]In this context we can distinguish two subtypes:
EOL comments ([to-the-]end-of-line), which can be placed after a command, and invariably extend to the end of the line (again, courtesy of jeb's answer):
ver & REM <comment>
takes advantage of the fact thatREM
is a valid command and&
can be used to place an additional command after an existing one.ver & :: <comment>
works too, but is really only usable outside of(...)
blocks, because its safe use there is even more limited than using::
standalone.Intra-line comments, which be placed between multiple commands on a line or ideally even inside of a given command.
Intra-line comments are the most flexible (single-line) form and can by definition also be used as EOL comments.
ver & REM^. ^<comment^> & ver
allows inserting a comment between commands (again, courtesy of jeb's answer), but note how<
and>
needed to be^
-escaped, because the following chars. cannot be used as-is:< > |
(whereas unescaped&
or&&
or||
start the next command).%= <comment> =%
, as detailed in dbenham's great answer, is the most flexible form, because it can be placed inside a command (among the arguments).It takes advantage of variable-expansion syntax in a way that ensures that the expression always expands to the empty string - as long as the comment text contains neither
%
nor:
Like
REM
,%= <comment> =%
works well both outside and inside(...)
blocks, but it is more visually distinctive; the only down-sides are that it is harder to type, easier to get wrong syntactically, and not widely known, which can hinder understanding of source code that uses the technique.Multi-line (whole-line block) comments:
James K's answer shows how to use a
goto
statement and a label to delimit a multi-line comment of arbitrary length and content (which in his case he uses to store usage information).Zee's answer shows how to use a "null label" to create a multi-line comment, although care must be taken to terminate all interior lines with
^
.Rob van der Woude's blog post mentions another somewhat obscure option that allows you to end a file with an arbitrary number of comment lines: An opening
(
only causes everything that comes after to be ignored, as long as it doesn't contain a ( non-^
-escaped))
, i.e., as long as the block is not closed.[1] Using
SET "foo=bar"
to define variables - i.e., putting double quotes around the name and=
and the value combined - is necessary in commands such asSET "foo=bar" & REM Set foo to bar.
, so as to ensure that what follows the intended variable value (up to the next command, in this case a single space) doesn't accidentally become part of it.(As an aside:
SET foo="bar"
would not only not avoid the problem, it would make the double quotes part of the value).Note that this problem is inherent to
SET
and even applies to accidental trailing whitespace following the value, so it is advisable to always use theSET "foo=bar"
approach.