我一直在写一些批处理文件,然后我看到了这个用户指南,它提供了很多信息。它告诉我的一件事是,行不仅可以用REM进行注释,还可以用::进行注释。它说:
批处理代码中的注释可以通过使用双冒号来生成,这比使用REM命令更好,因为标签在重定向符号之前被处理。::<remark>不会引起任何问题,但是rem <remark>会产生错误。
那么,为什么我看到的大多数指南和示例都使用REM命令呢?::适用于所有版本的Windows吗?
我一直在写一些批处理文件,然后我看到了这个用户指南,它提供了很多信息。它告诉我的一件事是,行不仅可以用REM进行注释,还可以用::进行注释。它说:
批处理代码中的注释可以通过使用双冒号来生成,这比使用REM命令更好,因为标签在重定向符号之前被处理。::<remark>不会引起任何问题,但是rem <remark>会产生错误。
那么,为什么我看到的大多数指南和示例都使用REM命令呢?::适用于所有版本的Windows吗?
当前回答
另一种替代方法是将注释表示为一个总是展开为零的变量展开。
变量名不能包含=,除了未记录的动态变量,比如 %=ExitCode%和%=C:%。任何变量名都不能在第一个位置后面包含=。所以我有时会使用下面的代码在括号内包含注释:
::This comment hack is not always safe within parentheses.
(
%= This comment hack is always safe, even within parentheses =%
)
它也是一种合并内联注释的好方法
dir junk >nul 2>&1 && %= If found =% echo found || %= else =% echo not found
前导=不是必须的,但我喜欢它的对称性。
有两个限制:
1)注释不能包含%
2)评论不能包含:
其他回答
好问题……我也一直在寻找这个功能…
经过几次测试和技巧,似乎更好的解决方案是更明显的…
——>最好的方法,我发现这样做,防止解析器完整性失败,是重用REM:
echo this will show until the next REM &REM this will not show
你也可以使用多行“NULL LABEL”技巧… (不要忘记行末的^以保持连贯性)
::(^
this is a multiline^
comment... inside a null label!^
dont forget the ^caret at the end-of-line^
to assure continuity of text^
)
当我意识到我可以使用label::来注释和注释代码时,REM对我来说只是看起来很难看。如前所述,双冒号在()阻塞代码中使用时可能会导致问题,但我发现了一种变通方法,即在标签::和:空格之间交替使用
:: This, of course, does
:: not cause errors.
(
:: But
: neither
:: does
: this.
)
它不像REM那样丑陋,而且实际上为你的代码添加了一点风格。
所以在代码块之外,我使用::,在代码块内部,我在::和:之间交替。
顺便说一下,对于大量注释,比如批处理文件的头,您可以通过浏览注释来完全避免使用特殊命令和字符。这让你可以使用任何你想要的方法或风格的标记,尽管事实是,如果CMD实际上试图处理这些行,它会抛出一个嘘声。
@echo off
goto :TopOfCode
=======================================================================
COOLCODE.BAT
Useage:
COOLCODE [/?] | [ [/a][/c:[##][a][b][c]] INPUTFILE OUTPUTFILE ]
Switches:
/? - This menu
/a - Some option
/c:## - Where ## is which line number to begin the processing at.
:a - Some optional method of processing
:b - A third option for processing
:c - A forth option
INPUTFILE - The file to process.
OUTPUTFILE - Store results here.
Notes:
Bla bla bla.
:TopOfCode
CODE
.
.
.
使用任何你想要的符号*,@等等。
该页告诉我们,在某些限制条件下,使用“::”会更快 只是选择时要考虑的一点
另一种替代方法是将注释表示为一个总是展开为零的变量展开。
变量名不能包含=,除了未记录的动态变量,比如 %=ExitCode%和%=C:%。任何变量名都不能在第一个位置后面包含=。所以我有时会使用下面的代码在括号内包含注释:
::This comment hack is not always safe within parentheses.
(
%= This comment hack is always safe, even within parentheses =%
)
它也是一种合并内联注释的好方法
dir junk >nul 2>&1 && %= If found =% echo found || %= else =% echo not found
前导=不是必须的,但我喜欢它的对称性。
有两个限制:
1)注释不能包含%
2)评论不能包含:
下面的回答试图对本页上许多很棒的答案进行实用主义的总结:
杰布的回答很好,值得特别提一下,因为它真的很深入,涵盖了许多边缘情况。 值得注意的是,他指出一个错误构造的变量/参数引用,比如%~,可以破坏下面的任何解——包括REM行。
全行注释——唯一直接支持的样式:
REM(或其大小写变体)是唯一的官方评论结构,也是最安全的选择——参见Joey的有用答案。 ::是一个(广泛使用的)黑客,它有优点和缺点: 优点: 视觉上的独特性,以及可能的打字便捷性。 速度,尽管这可能不太重要——看看jeb的精彩回答和Rob van der Woude的精彩博客文章。 缺点: 在(…)块内部,::可以破坏命令,安全使用的规则是限制性的,不容易记住-见下文。
如果你想使用::,你有这些选择:
或者:为了安全起见,在(…)块中创建一个异常并在那里使用REM,或者完全不在(…)块中放置注释。 或者:记住安全使用::inside(…)的痛苦的限制性规则,这些规则总结在下面的代码片段中:
@echo off
for %%i in ("dummy loop") do (
:: This works: ONE comment line only, followed by a DIFFERENT, NONBLANK line.
date /t
REM If you followed a :: line directly with another one, the *2nd* one
REM would generate a spurious "The system cannot find the drive specified."
REM error message and potentially execute commands inside the comment.
REM In the following - commented-out - example, file "out.txt" would be
REM created (as an empty file), and the ECHO command would execute.
REM :: 1st line
REM :: 2nd line > out.txt & echo HERE
REM NOTE: If :: were used in the 2 cases explained below, the FOR statement
REM would *break altogether*, reporting:
REM 1st case: "The syntax of the command is incorrect."
REM 2nd case: ") was unexpected at this time."
REM Because the next line is *blank*, :: would NOT work here.
REM Because this is the *last line* in the block, :: would NOT work here.
)
模仿其他注释样式——内联和多行:
注意,批处理语言不直接支持这些样式,但是可以进行模拟。
内联注释:
*下面的代码片段使用ver作为任意命令的替身,以便于实验。 *要使SET命令在内联注释中正确工作,请双引号name=value部分;例如,SET "foo=bar".[1]
在这种情况下,我们可以区分两个子类型:
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 that REM 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.
多行(全行块)注释:
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 as SET "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 the SET "foo=bar" approach.