【问题标题】:How to "comment-out" (add comment) in a batch/cmd?如何在批处理/cmd中“注释掉”(添加注释)?
【发布时间】:2012-07-01 10:20:32
【问题描述】:

我有一个批处理文件,它运行几个执行表修改的 python 脚本。

  1. 我想让用户注释掉他们不想运行的 1-2 个 python 脚本,而不是从批处理文件中删除它们(所以下一个用户知道这些脚本作为选项存在!)

  2. 我还想添加 cmets 以特别提醒他们注意在运行批处理文件之前需要在批处理文件中更新的变量。我看到我可以使用REM。但它看起来更像是在用户运行后更新用户的进度。

是否有更恰当地添加评论的语法?

【问题讨论】:

  • 在此处查看优秀答案stackoverflow.com/q/12407800/1011025
  • 您可以使用Rem Sth 命令或使用此标记::: Sth
  • 我更喜欢使用: - REM 用于 cmets - &REM 用于内联 cmets

标签: batch-file cmd comments comment-conventions


【解决方案1】:

使用::REM

::   commenttttttttttt
REM  commenttttttttttt

但是(正如人们所说):

  • :: 不能内联工作;添加& 字符:
    your commands here & :: commenttttttttttt
  • 内部嵌套部分(IF/ELSEFOR 循环等...):: 后面应跟普通行,否则会报错(在此处使用REM)。
  • :: 也可能在 setlocal ENABLEDELAYEDEXPANSION 内失败

【讨论】:

  • 双冒号 :: 是最干净的 .bat 注释。并且可以用在一行的开头或中间!
  • 像这样内联完成时对我不起作用。 cd "C:\Folder" ::this throws a syntax error
  • 对于与示例说明的同一行的注释,您需要在代码和注释::之间添加&。为了说明,打开 cmd 提示符并运行dir ::blah,它没有列出. 的内容,并与dir & ::blah 进行比较,它确实
  • 警告,使用:: 会导致带有setlocal ENABLEDELAYEDEXPANSIONfor 的脚本出错
  • Examples 了解使用 :: 标签作为 cmets 会导致难以预料的错误。称这个干净有点误导@ATSiem
【解决方案2】:

rem 命令确实适用于 cmets。运行脚本后,它本质上不会更新任何人。不过,一些脚本作者可能会以这种方式使用它而不是 echo,因为默认情况下,批处理解释器会在处理之前打印每个命令。由于rem 命令不执行任何操作,因此可以安全地打印它们而不会产生副作用。要避免打印命令,请在其前面加上 @,或者,要在整个程序中应用该设置,请运行 @echo off。 (echo off 是为了避免打印更多命令;@ 是为了避免在 echo 设置生效之前打印 that 命令。)

所以,在你的批处理文件中,你可以使用这个:

@echo off
REM To skip the following Python commands, put "REM" before them:
python foo.py
python bar.py

【讨论】:

  • 你也可以使用两个冒号“::”。这是在批处理文件运行时将注释添加到批处理文件中而不显示或执行该行的两种方法之一。与 REM 不同,无论 ECHO off 是否在批处理文件中,此行都不会显示。
  • @Brent81 我觉得这应该是正确的答案。当使用语法高亮时,REM 命令实际上并没有将文本高亮为“注释掉”。
  • 双冒号是“无效标签”;这是一篇解释它的文章,以及为什么它的性能可能比 REM 更好(尤其是在软盘上!),并且它不适用于缩进代码块(仅在第一个字符上):robvanderwoude.com/comments.php
  • 有趣。我认为 REM 是“整行注释”,而双冒号是“内联注释”,例如 REM This whole line is a comment @echo off :: This comment is inline
  • @Alhadis,Perl 的配置脚本是用 Bourne shell 编写的,而不是 Windows 批处理,那么它与这里有什么关系?此外,冒号命令是有效的 Bourne 语法并不是“额外的副作用”;这正是 为什么 在那个 Bourne 脚本 中使用它。它用于支持 cmets 的 #,因为 # 显然在 Configure 旨在支持的 所有 shell 中可能不是有效的注释指示符;见第 3 行。
【解决方案3】:

不,普通的旧批处理文件使用 REM 作为注释。 ECHO 是在屏幕上打印内容的命令。

要“注释掉”文件的部分,您可以使用GOTO。所有这些命令/技术的示例:

REM it starts here the section below can be safely erased once the file is customised
ECHO Hey you need to edit this file before running it!  Check the instructions inside
ECHO Now press ctrl-c to interrupt execution or enter to continue
PAUSE
REM erase the section above once you have customised the file
python executed1.py
ECHO Skipping some stuff now
GOTO End
python skipped1.py
python skipped2.py
:END
python executed2.py

我能说什么?批处理文件是时代的遗物,它们又笨又丑。

您可以阅读更多on this website

编辑:稍微修改了示例,使其包含您显然正在寻找的元素。

【讨论】:

    【解决方案4】:

    在计算机不是很快的日子里,最好使用 :: 而不是 REM。 REM'ed 行被读取,然后被忽略。 ::'ed 行一直被忽略。这可以在“过去”中加速您的代码。此外,在 REM 之后你需要一个空格,在 :: 之后你不需要。

    正如第一条评论中所说:您可以将信息添加到您认为需要的任何行中

    SET DATETIME=%DTS:~0,8%-%DTS:~8,6% ::Makes YYYYMMDD-HHMMSS
    

    至于跳过部分。 将 REM 放在每一行的前面可能相当耗时。 如前所述,使用 GOTO 跳过部分是跳过大段代码的简单方法。请务必在您希望代码继续运行的位置设置 :LABEL。

    SOME CODE
    
    GOTO LABEL  ::REM OUT THIS LINE TO EXECUTE THE CODE BETWEEN THIS GOTO AND :LABEL
    
    SOME CODE TO SKIP
    .
    LAST LINE OF CODE TO SKIP
    
    :LABEL
    CODE TO EXECUTE
    

    【讨论】:

    • 如何忽略双冒号行而不被读取?解释器在将其识别为双冒号之前不是必须先阅读该行吗?
    • @RobKennedy 在我阅读答案时,它不会在 :: 之后读取任何内容,而 REM 之后的所有内容都会被读取。
    • 如果命令解释器停止读取,@James,那么它将永远不会执行任何文件。它显然需要继续阅读以发现注释在哪里结束以及文件的下一行从哪里开始。它必须与 ::rem 同等地做到这一点。
    • @RobKennedy,我还认为它暗示它只适用于命令所在的行。
    • @RobKennedy 它会读取,但不会解析(或处理)它读取的内容,它只会跳到下一个\n 和然后再次开始解析[需要引用]
    【解决方案5】:

    多行 cmets

    如果您要注释掉大量行,那么最好制作多行 cmets,而不是注释掉每一行。

    this post by Rob van der Woude on comment blocks:

    批处理语言没有注释块,虽然有办法 达到效果。

    GOTO EndComment1
    This line is comment.
    And so is this line.
    And this one...
    :EndComment1
    

    你可以使用GOTOLabel和:Label来制作block cmets。

    或者,如果注释块出现在批处理文件的末尾,您可以 在代码末尾写EXIT,然后为您的任意数量的 cmets 理解。

    @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...
    

    【讨论】:

    【解决方案6】:

    将 cmets 与命令放在同一行:使用 & :: comment

    color C          & :: set red font color
    echo IMPORTANT INFORMATION
    color            & :: reset the color to default
    

    说明:

    & separates two commands,所以在这种情况下,color C 是第一个命令,:: set red font color 是第二个命令。


    重要:

    这个带有注释的语句在直觉上看起来是正确的:

    goto error1         :: handling the error
    

    但这不是评论的无效使用。它之所以有效,只是因为goto 忽略了第一个参数之后的所有参数。证明很简单,这个goto 也不会失败:

    goto error1 handling the error
    

    但类似的尝试

    color 17            :: grey on blue
    

    由于 color 命令未知的 4 个参数导致命令执行失败:::greyonblue

    它只能作为:

    color 17     &      :: grey on blue
    

    所以和号是不可避免的。

    【讨论】:

    • 从其他答案看来,和号是不需要的?
    • @Snaptastic - 在这一点上其他答案实际上是错误的,请参阅我最近的编辑。
    • 这似乎是正确的方法;它甚至在我的 IDE 中作为注释突出显示。
    【解决方案7】:

    您可以使用::REM 注释掉某些内容:

    your commands here
    :: commenttttttttttt
    

    your commands here
    REM  commenttttttttttt
    

     

    要在命令的同一行上执行此操作,您必须添加一个 & 符号:

    your commands here      & ::  commenttttttttttt
    

    your commands here      & REM  commenttttttttttt
    

     

    注意:

    • 在嵌套逻辑(IF-ELSEFOR 循环等...)中使用 :: 会导致错误。在这些情况下,请改用 REM

    【讨论】:

    • 这是基于 T.Todua 的回答。我觉得他们的回答很好,但遗漏了一些重要的细节,但他们回滚了我的编辑,所以我将我的修改变成了自己的答案。
    【解决方案8】:

    您可以使用以下语法将 cmets 添加到批处理文件的末尾:

    @echo off
    :: Start of code
    ...
    :: End of code
    
    (I am a comment
    So I am!
    This can be only at the end of batch files
    

    只要确保你从不使用右括号。

    署名:Leo Guttirez Ramirez on https://www.robvanderwoude.com/comments.php

    【讨论】:

      【解决方案9】:

      这是一个老话题,我想在这里补充一下我的理解,以扩展这个有趣话题的知识。

      REM 和 :: 之间的主要区别是:

      REM 本身就是一个命令,而 :: 不是。

      我们可以把 :: 当作一个记号,一旦 CMD 解析器遇到一行中的第一个非空格就是这个 :: 记号,它就会跳过整行并读取下一行。这就是为什么 REM 后面应该至少有一个空格才能作为该行的注释,而 :: 后面不需要任何空格。

      REM 本身就是一个命令,最好从下面的FOR 语法中理解

      基本的 FOR 语法如下

      FOR %v in (set) DO <Command> [command param] 
      

      这里&lt;Command&gt;可以是任何有效的命令 所以我们可以将下面的有效命令行写成rem is a command

      FOR %i in (1,2,3) DO rem echo %i
      

      但是,我们不能写下面这行,因为:: 不是命令

      FOR %i in (1,2,3) DO :: echo %i
      

      【讨论】:

      • 从技术上讲,:: 是一个(无效)标签(解释了它的行为),因此不应使用(尽管它仍然很常见)
      【解决方案10】:

      您可以将::rem 用于cmets。

      评论时,请使用::,因为它快 3 倍。示例显示here

      仅当 cmets 在 if 中时,才使用 rem,因为冒号可能会出错,因为它们是标签。

      【讨论】:

        【解决方案11】:

        评论一行

        对于评论行使用REM or :: 虽然:: 可能fail inside brackets

        在以!&lt;delimiter&gt; 开头的延迟扩展行内将被忽略,因此可用于 cmets:

        @echo off
        
        setlocal enableDelayedExpansion
        
        echo delayed expansion activated
        !;delayed expansion commented line
        echo end of the demonstration
        

        行尾注释

        对于行尾的 cmets,您可以再次使用 rem::&amp; 结合使用:

        echo --- &:: comment (should not be the last line in the script)
        echo --- &rem comment
        

        在文件末尾注释

        注意将在exit 命令之后进行解析,您可以使用它将 cmets 放在文件末尾:

        @echo off
        
        echo commands
        
        exit /b 
        
        -------------------
        commnts at the end 
        of the file
        ------------------
        

        内联 cmets

        不存在的变量的扩展被替换为空,并且用=设置变量相当困难,你可以use this for inline comments

        @echo off
        
        echo long command %= this is a comment =% with an inline comment
        

        多行 cmets

        对于多行 cmets GOTO(用于外括号)和带有条件执行的REM(用于内括号)可以使用。 More details here:

        @echo off
        
        echo starting script
        
        goto :end_comments
         comented line 
         one more commented line
        :end_comments
        
        echo continue with the script
        
        (
            echo demonstration off
            rem/||(
              lines with
              comments
            )
            echo multiline comment inside
            echo brackets
        )
        

        同样的技术用宏美化:

        @echo off
        
        ::GOTO comment macro
        set "[:=goto :]%%"
        ::brackets comment macros
        set "[=rem/||(" & set "]=)"
        
        ::testing
        echo not commented 1
        
        %[:%
          multi 
          line
          comment outside of brackets
        %:]%
        
        echo not commented 2
        
        %[:%
          second multi 
          line
          comment outside of brackets
        %:]%
        
        ::GOTO macro cannot be used inside for
        for %%a in (first second) do (
            echo first not commented line of the %%a execution
            %[%
                multi line
                comment
            %]%
            echo second not commented line of the %%a execution
        )
        

        【讨论】:

          【解决方案12】:

          我更喜欢使用:

          • 用于 cmets 的 REM
          • &REM 用于内联 cmets

          例子:

          @echo off
          set parameter1=%1%
          REM test if the parameter 1 was received
          if defined parameter1 echo The parameter 1 is %parameter1% &REM Display the parameter
          

          【讨论】:

          • 我看不到您的回答在哪里添加了更多信息。已经有相同内容的答案,至少有一个是 8 岁
          • 这是一个最简单的答案...没有复杂性
          猜你喜欢
          • 2011-02-04
          • 2023-03-12
          • 2015-12-23
          • 2014-12-11
          • 1970-01-01
          • 1970-01-01
          • 2023-03-16
          • 1970-01-01
          • 2015-04-26
          相关资源
          最近更新 更多