Regardless of the programming or scripting language used, it is always a good idea to insert comments in scripts, explaining what the next lines or block of code is trying to accomplish, how and/or why.
Comments in batch files are usually placed in lines starting with REM
(REMarks).
If you have many lines REM
ed out, this may slow down COMMAND.COM's processing of the batch file.
As you probably know, COMMAND.COM reads a batch file, executes one command line, reads the batch file again, executes the next command line, etcetera.
This means each comment line causes one extra reread of the batch file; no problem when read from harddisk, but it may slow down batch file execution from slow floppy or network drives.
A workaround I have seen many times (back in the old days, when I was young, and dinosaurs roamed the Earth and harddisks were 20MB) is to convert the comment line to a label by starting the line with a colon ( : ).
COMMAND.COM skips labels it doesn't have to jump to.
This method has the disadvantage that your batch file may "accidently" really use the label to jump to.
As Marc Stern points out in one of his MS-DOS batch files Tips & Tricks, this can be solved by using a double colon ( :: ) as the first characters of the comment line.
That way, the label is invalid but still treated as a label, and skipped (i.e. the next line is read immediately by COMMAND.COM, without the need to reopen the batch file). This may speed up reading large blocks of comment lines from slow (floppy) drives.
This same trick works in CMD.EXE (the command processor in Windows NT 4 and later) as well (not sure about OS/2 though)...
...but with some restrictions!
REM
is a true command that may be used anywhere within a command line.
Though I doubt there is much use for a command like:
IF EXIST C:\AUTOEXEC.BAT REM AUTOEXEC.BAT exists
it is valid and won't generate an error message in any DOS or Windows version.
Labels, on the other hand, whether valid or not, should always start at the first non-whitespace character in a command line.
REM Comment line 1 REM Comment line 2 :Label1 :Label2 :: Comment line 3 :: Comment line 4 IF EXIST C:\AUTOEXEC.BAT REM AUTOEXEC.BAT exists
are all allowed.
However,
IF EXIST C:\AUTOEXEC.BAT :: AUTOEXEC.BAT exists
will result in a Syntax error message.
A true pitfall are code blocks, several commands grouped between parentheses and interpreted as a single command line by CMD.EXE!
IF EXIST C:\AUTOEXEC.BAT ( :: Comment line 1 ECHO Do something :: Comment line 2 )
will result in an error message stating:
) was unexpected at this time.
and:
IF EXIST C:\AUTOEXEC.BAT ( :: Comment line 1 ECHO Do something :: Comment line 2 :: Comment line 3 )
will result in another error message:
Do something
The system cannot find the drive specified.
The same is true for FOR loops.
Try and see for yourself:
FOR %%A IN (1 2 3) DO ( :: Comment line 1 ECHO Do something :: Comment line 2 )
and:
FOR %%A IN (1 2 3) DO ( :: Comment line 1 ECHO Do something :: Comment line 2 :: Comment line 3 )
will also result in error messages.
The errors are caused by labels being used within code blocks.
What may come as a surprise is that the following code does work flawlessly:
FOR %%A IN (1 2 3) DO ( :: Comment line 1 ECHO Do something :: Comment line 2 ECHO Do something )
It turns out that a single ::
comment line, immediately followed by a non-blank command line, will work even inside code blocks!
Replace the double colons by REM
statements and these samples will all run without a glitch.
Better still, don't use comments within code blocks at all, but place them just before the code blocks instead:
:: Comment line 1 :: Comment line 2 :: Comment line 3 FOR %%A IN (1 2 3) DO ( ECHO Do something )
or:
REM Comment line 1 REM Comment line 2 REM Comment line 3 FOR %%A IN (1 2 3) DO ( ECHO Do something )
( REM comment1 ECHO comment1 ) (REM comment2 & ECHO comment2) REM comment3 & ECHO comment3 ECHO comment4
The code above use 3 code blocks, each with a REM
command followed by an ECHO
command.
The 3 code blocks are followed by a fourth "stand-alone" ECHO
command.
The 3 code blocks are supposed to behave more or less identically, at least in older versions like Windows NT 4 and 2000...
Well, in Windows 7 they don't!
D:\>test_REM_comments_in_code_blocks.bat D:\>( REM comment1 ECHO comment1 ) comment1 D:\> D:\>
comment1
is the only comment ECHO
ed.
The code block for comment2
only displays an empty line.
The code block for comment3
is never reached...
It would seem the code block for comment2
aborts the batch file without warning.
Remove that code block, and the rest will be executed as expected.
So, can you explain this behaviour...?
The answer can be found at the end of this page.
More information on the subject:
%= inline comments =%
), each with its own list of pros and consREM
(Thanks for Lee Wilbur and Michael Klement)
A possible pitfall, pointed out by Joost Kop, is a REM
to comment out a line that uses redirection, as in:
REM DIR > logfile.log
In CMD.EXE (Windows NT 4 and later) the line is completely ignored (as was probably intended), but COMMAND.COM (MS-DOS, Windows 9x) interprets this line as "redirect the output of REM
to logfile.log", thus emptying the file logfile.log or creating a 0 bytes file logfile.log.
Note: | I would like to mention one situation where I always prefer REM over double colons: batch files for silent installations.Why? I always leave out the @ECHO OFF since silent installations will usually run in the background.When testing, however, I will run the batch files interactively, and then the REM ed comments will be displayed (remember, no @ECHO OFF ) because they are commands, not labels. |
REM
is the standards-compliant, documented statement to insert comments in batch filesGOTO
command just before the comments, jumping to a label just after the comments, is a safer and more standards-compliant way to speed up batch execution from slow drivesREM
if you have to (but be aware of pitfalls if you do use REM
)REM
or double colons to temporarily "disable" a command line, especially when it contains piping, redirection or variables
REM
to block Standard InputA really useful trick is to use REM
combined with piping, as in:
REM | CHOICE /C:AB /T:A,5 > NUL
The CHOICE command in itself would time out after 5 seconds (/T), except if someone presses a key not specified by /C, in which case the count down would be aborted.
By using REM
and piping its (always empty) standard output to CHOICE's standard input, this standard input will not receive keypresses from the console (keyboard) anymore.
So pressing a button neither speeds up CHOICE
nor stops it.
(I borrowed this technique from "Outsider", one of the alt.msdos.batch newsgroup's "regulars", and added the /C parameter to make it language independent)
Note: | This trick will work in COMMAND.COM only, not in CMD.EXE. In CMD.EXE everything after the REM "command" is considered comment, including the pipe symbol.For CMD.EXE, the following command could be used (Windows XP and later): TYPE NUL | CHOICE /C:AB /T:A,5 > NUL Read my wait page to find out how to set delays in Windows NT 4 and later. |
Several languages allow complete code blocks to be commented out by using /*
and */
"tags".
Rexx, for example, will treat the whole text marked red as comment:
Say "This line is true code"
/*
But this line is comment.
And so is this line.
And this one...
*/
The batch language doesn't have comment blocks, though there are ways to accomplish the effect:
@ECHO OFF
REM Do something
•
•
REM End of code
REM Start of comment block 1
GOTO EndComment1
This line is comment.
And so is this line.
And this one...
:EndComment1
Or, if the comment block appears at the end of the batch file:
@ECHO OFF
REM Do something
•
•
REM End of code; use GOTO:EOF instead of EXIT for Windows NT and later
EXIT
Start of comment block at end of batch file
This line is comment.
And so is this line.
And this one...
Leo Gutierrez Ramirez came up with an even shorter way to accomplish a comment block at the end of a batch file:
@ECHO OFF
REM Do something
•
•
REM End of code
(Start of comment block at end of batch file
This line is comment.
And so is this line.
And this one...
Just make sure you never use a closing parenthesis.
Note: | This trick does have one major disadvantage: the use of parentheses in the comment block is not allowed. |
Recently, Vasco Rato showed me the solution to the mysteriously disappearing code.
If you read Leo Gutierrez Ramirez' trick of the missing closing parenthesis, you'll see that that is exactly what happens.
The following line of code:
(REM comment2 & ECHO comment2)
is equivalent to
(REM whatever
since everything following the REM
statement, including the closing parenthesis, is comment, i.e. not interpreted!
Since there were no other parentheses in the "mystery code block" after this comment, everything from the opening parenthesis before the REM
statement up to the end of the code is then a "Leo Gutierrez Ramirez style" comment block.
As Vasco states: everything behaves as one would expect it to.
Thanks Vasco and Leo
page last modified: 2019-03-12; loaded in 0.0018 seconds