我一直在写一些批处理文件,然后我看到了这个用户指南,它提供了很多信息。它告诉我的一件事是,行不仅可以用REM进行注释,还可以用::进行注释。它说:
批处理代码中的注释可以通过使用双冒号来生成,这比使用REM命令更好,因为标签在重定向符号之前被处理。::<remark>不会引起任何问题,但是rem <remark>会产生错误。
那么,为什么我看到的大多数指南和示例都使用REM命令呢?::适用于所有版本的Windows吗?
我一直在写一些批处理文件,然后我看到了这个用户指南,它提供了很多信息。它告诉我的一件事是,行不仅可以用REM进行注释,还可以用::进行注释。它说:
批处理代码中的注释可以通过使用双冒号来生成,这比使用REM命令更好,因为标签在重定向符号之前被处理。::<remark>不会引起任何问题,但是rem <remark>会产生错误。
那么,为什么我看到的大多数指南和示例都使用REM命令呢?::适用于所有版本的Windows吗?
当前回答
关于这个话题的一个非常详细和分析性的讨论可以在这个页面上找到
它有示例代码和不同选项的优点/缺点。
其他回答
下面的回答试图对本页上许多很棒的答案进行实用主义的总结:
杰布的回答很好,值得特别提一下,因为它真的很深入,涵盖了许多边缘情况。 值得注意的是,他指出一个错误构造的变量/参数引用,比如%~,可以破坏下面的任何解——包括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.
关于这个话题的一个非常详细和分析性的讨论可以在这个页面上找到
它有示例代码和不同选项的优点/缺点。
该页告诉我们,在某些限制条件下,使用“::”会更快 只是选择时要考虑的一点
好问题……我也一直在寻找这个功能…
经过几次测试和技巧,似乎更好的解决方案是更明显的…
——>最好的方法,我发现这样做,防止解析器完整性失败,是重用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^
)
James K,我很抱歉我说错了很多。我所做的测试如下:
@ECHO OFF
(
:: But
: neither
:: does
: this
:: also.
)
这符合您对交替的描述,但失败于“)was unexpected at This time.”错误消息。
我今天做了一些进一步的测试,发现交替不是关键,但关键似乎是有偶数行,没有任何两行在一行以双冒号(::)开始,也没有双冒号结束。考虑以下几点:
@ECHO OFF
(
: But
: neither
: does
: this
: cause
: problems.
)
这个工作!
但还要考虑到这一点:
@ECHO OFF
(
: Test1
: Test2
: Test3
: Test4
: Test5
ECHO.
)
当以命令结尾时,注释数量为偶数的规则似乎并不适用。
不幸的是,这只是奇怪的足够,我不确定我想要使用它。
实际上,最好的解决方案,也是我能想到的最安全的解决方案是,如果一个像notepad++这样的程序将REM读取为双冒号,然后在保存文件时将双冒号写入REM语句。但我不知道这样一个程序,我也不知道任何notepad++的插件,这样做。