当前位置: 首页 > 知识库问答 >
问题:

我应该在批处理文件中使用哪种注释样式?

郑乐池
2023-03-14

我一直在写一些批处理文件,我偶然发现了这本用户指南,它提供了大量信息。它告诉我的一件事是,行不仅可以用REM注释,还可以用注释。上面写着:

批处理代码中的注释可以使用双冒号进行,这比使用REM命令更好,因为标签是在重定向符号之前处理的。::

那么,为什么我看到的大多数指南和示例都使用REM命令呢?是否适用于所有版本的Windows?


共有3个答案

陈实
2023-03-14

这个答案试图对本页上的许多伟大答案进行务实总结:

jeb的伟大答案值得特别提及,因为它确实深入,涵盖了许多边缘案例
值得注意的是,他指出,错误构造的变量/参数引用,如%~,可能会破坏以下任何解决方案,包括REM

>

::是一个(广泛使用的)hack,它有优点和缺点:

>

  • 优点:

    • 视觉上的独特性,可能还有打字的便利性

    欺骗:

    • 内部(…) 块,可以破坏命令,安全使用的规则是有限制的,不容易记住-见下文

    如果你想使用,你有以下选择:

    • 或者:为了安全起见,在(…)中做一个例外 块并在那里使用REM,或者不要在内放置注释(…) 全部
    • 或者:在(…)中记住安全使用的痛苦限制规则 ,总结在以下代码片段中:
    @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部分;e、 例如,设置“foo=bar”[1]

    在这种情况下,我们可以区分两种亚型:

    >

    • ver

    行内注释,可以放在一行的多个命令之间,理想情况下甚至放在给定命令的内部
    行内注释是最灵活的(单行)形式,根据定义也可以用作下线注释。

    >

  • <代码>版本

    %=

    多行(整行块)注释:

    >

    Zee的回答显示了如何使用“空标签”创建多行注释,但必须注意用^终止所有内部行。

    Rob van der Woude的博客文章提到了另一个有点模糊的选项,它允许您以任意数量的注释行结束文件:打开只会导致后面的所有内容都被忽略,只要它不包含(非^-转义),即只要块没有关闭。

    [1]使用SET"foo=bar"定义变量-即在名称和=周围加上双引号以及组合的值-在命令中是必要的,例如SET"foo=bar"

  • 陶璞
    2023-03-14

    REM可以注释完整的行,如果不是第一个标记的末尾,也可以在行尾注释多行插入符号。

    REM This is a comment, the caret is ignored^
    echo This line is printed
    
    REM This_is_a_comment_the_caret_appends_the_next_line^
    echo This line is part of the remark
    

    REM后跟一些字符.:\/=的工作方式有点不同,它不注释&号,因此您可以将其用作内联注释。

    echo First & REM. This is a comment & echo second
    

    但是为了避免现有文件出现问题,比如REMREM.batREM;。bat只能使用经过修改的变体。

    REM^;<space>Comment
    

    和字符也可以是;,:\/=

    REM的速度大约是(在Win7SP1上测试,有100000条注释行)的6倍
    对于正常使用,这并不重要(每条评论行58µs与360µs)

    A始终执行行尾插入符号。

    :: This is also a comment^
    echo This line is also a comment
    

    标签和注释标签在括号块中有一个特殊的逻辑
    它们总是跨越两行,因此:goto命令不起作用
    因此,不建议将它们用于括号块,因为它们通常会导致语法错误。

    ECHO打开时,会显示REM行,但没有注释

    这两种方法都不能真正注释掉行的其余部分,因此简单的%~将导致语法错误。

    REM This comment will result in an error %~ ...
    

    但是REM能够在早期阶段停止批处理解析器,甚至在特殊字符阶段完成之前。

    @echo ON
    REM This caret ^ is visible
    

    你可以用

    存在带有百分号的注释样式。

    实际上,这些都是变量,但它们被扩展为零
    但优点是,即使没有

    echo Mytest
    set "var=3"     %= This is a comment in the same line=%
    

    建议批处理宏使用百分比样式,因为它不会更改运行时行为,因为定义宏时注释将被删除。

    set $test=(%\n%
    %=Start of code=% ^
    echo myMacro%\n%
    )
    

    简而言之:

    • %==%似乎具有相同的性能

    欲了解更多信息,请参见:关于批量评论的问题*。bat文件和速度

    赫连华皓
    2023-03-14

    tl;dr:REM是在批处理文件中嵌入注释的有文档记录且受支持的方法

    本质上是一个无法跳转到的空白标签,而REM是一个实际的命令,它什么也不做。在这两种情况下(至少在Windows 7上),重定向操作符的存在都不会导致问题。

    然而,::在某些情况下会在块中出现错误行为,被解析为某种驱动器号,而不是标签。我对确切的位置有点模糊,但仅此一点就足以让我只使用REM。这是在批处理文件中嵌入注释的一种有文档记录且受支持的方式,而只是特定实现的产物。

    下面是一个例子,其中FOR循环中产生问题。

    这个例子在名为test的文件中不起作用。bat在您的桌面上:

    @echo off
    for /F "delims=" %%A in ('type C:\Users\%username%\Desktop\test.bat') do (
        ::echo hello>C:\Users\%username%\Desktop\text.txt
    )
    pause
    

    虽然此示例将正确用作注释:

    @echo off
    for /F "delims=" %%A in ('type C:\Users\%username%\Desktop\test.bat') do (
        REM echo hello>C:\Users\%username%\Desktop\text.txt
    )
    pause
    

    问题似乎是在尝试将输出重定向到文件时。我最好的猜测是,它将解释为一个名为:echo的转义标签。

     类似资料:
    • 由于请求的不同用法和注释,我一直很困惑

    • 问题内容: 的(Java持久性API)规范有2名不同的方式来指定实体组合键:和。 我在映射的实体上同时使用了这两个注释,但是对于不太熟悉的人来说,这真是一个大麻烦。 我只想采用一种指定复合键的方法。哪个真的是最好的?为什么? 问题答案: 我认为这可能更冗长,因为无法使用任何字段访问运算符来访问整个主键对象。使用,您可以这样做: 这给构成组合键的字段提供了清晰的概念,因为它们都聚集在通过字段访问运算

    • 主要内容:使用Rem语句注释,注释使用::声明为创建的脚本添加注释或文档总是一个好习惯。 这是一个维护脚本用来理解脚本实际所做的事情所必需的注释。 例如,考虑下面这段没有注释形式的代码。 如果一个没有任何注释的脚本,普通人试图理解脚本,那么需要很多时间来理解脚本做些什么工作。 使用Rem语句注释 有两种方法可以在批处理脚本中创建注释; 一个是通过命令。 语句后的任何文本都将被视为注释,不会被执行。 以下是此声明的一般语法。 语法 其中是需要添

    • 我将guava jar文件添加到类路径中,但我的IDE(eclipse)说: Nullable无法解析为类型 但如果我ctrl+单击Nullable,我会看到蓝色下划线,然后看到下划线:

    • 我知道类似的问题已经被问过很多次了。但在阅读了这些帖子之后,我仍然感到非常困惑,尤其是在iOS 10中引入了之后。 官方文档提到了我可以处理远程通知的3种方法: 实现以在应用程序位于前台时处理通知 当应用程序处于后台或未运行时,实现 但文档中也提到:在iOS和tvOS中,系统将通知有效负载传递给app委托的方法 所以 要在应用处于后台/非活动状态时处理远程通知,我应该将我的代码放在3中的应用程序委

    • 我有一个定制的作家,它很好用;但是,我想通过JobParameters来设置我的输出文件的名称,而不是在我的配置中使用固定的字符串。为了做到这一点,我添加了@stepscope注释和参数,就像我对ItemReader所做的那样。 ItemWriter声明 步骤声明 这段代码不起作用,我得到一个WriterNotOpenException是因为我使用FlatFileItemWriter作为委托。 当