如何在命令行中可靠地使用`rem`而不忽略相邻命令?

我正在尝试使用rem命令在包含多个命令的命令行中放置注释。 下面是一些例子来说明我的意思:

 echo Hello & rem.Comment & echo world! (echo Hello & rem.Comment) & echo world! 

这工作得很好,每行的echo命令都按照我的预期执行。 的. 似乎修改rem命令的行为,以便它不会将剩余的行视为注释:

 Hello world! 

如果我放置一个空格 (或任何其他分隔符TAB,,,,, = )而不是. ,剩余的行,因此第二个echo将被忽略(对于第二个例子,会出现More?提示符,因为)是注释的一部分,而cmd期望closures)因为( ):

 Hello 

我发现旁边. ,以下字符也适用:/\[]+
逃生的分隔符还有什么作用: ^ SPACE^ TAB^,^;^=

不过, 有没有一种安全可靠的方法呢?

我很高兴看到一个适用于命令提示符和batch file的解决scheme。


根据这个外部参考 ,熟悉的语法echo. 在某些情况下返回一个空白行失败,因此使用echo(推荐这是唯一可靠的方法。

但是,对于rem(不工作, rem(之后的所有东西rem(不被认为是一个命令。


由于我知道在Windows XP中rem命令的一个奇怪的错误(引用这个外部链接 : rem %~ ),我感兴趣的是适用于Windows Vista,Windows 7或更高版本的解决scheme。

“怪异的” REM %~ “bug”不仅限于XP。 它存在于使用CMD.EXE的所有现代版本的Windows中。 看完你的问题后,我给SS64的西蒙写了一封注释 ,说明了这个问题。 如果变量var存在,REM也可能失败,并且你有rem %var:=

所以在技术上,没有保证安全的方式来盲目使用REM。

但是,如果您愿意接受致命的%扩展风险,则大多数列出的黑客都可以安全使用,但是只有当该行通过&&&包含至少一个附加命令时才可以使用。

REM. 如果存在名为REM (无扩展名)的文件,在任何情况下都不安全。

如果当前文件夹包含名为test.bat的文件,并且您使用REM\..\test.bat ,则文件夹分隔符\/始终失败。

以类似的方式, REM:\..\test.bat总是失败。

其他每一个黑客都可以在类似的情况下单独失败。 例如, REM^[tab]\..\test.bat独立运行,但是如果与另一个命令连接,则会运行。 这是我找到的唯一一种情况,其中+[]^[tab]可能会失败。

还有其他一些黑客可能会失败的情况。

如果存在remC.bat ,则在文件名中有效的集合C( ^[space]^, ^;^= )中的任何字符都可能会失败。 例如,以下失败单独:

 rem^ Fails if "rem .bat" exists 

然而,当与另一个命令串联时,它们都是安全的:

 echo OK&rem^ This is safe rem^ This is safe &echo OK 

临时更新

上面的一些是错误的。 正在进行调查, 网址为http://www.dostips.com/forum/viewtopic.php?f=3&t=6895&p=44813#p44813

我相信以下是保证在所有情况下都能正常工作的最简单的形式(不考虑无效的扩展)

 REM: At least one space (or other token delimiter) must be after : REM\ At least one space (or other token delimiter) must be after \ REM/ At least one space (or other token delimiter) must be after / REM^[tab] At lease one space (or other token delimiter) must be after [tab] 

但是我不会纠正以前的信息,直到尘埃落定

结束临时更新


我最喜欢使用内联注释的方式是使用不可变的变量。 只有动态伪变量可以在名称中包含= ,并且任何变量名都不能包含两个= 。 所以我喜欢用%= Remark goes here =% 。 这种形式的美妙之处在于它可以在任何地方使用而不受惩罚,只要注释不包含%: 。 它甚至可以在带括号的代码块中安全地使用。

 for %%F in (*) do ( %= Comment within code block =% %= 2nd comment within code block =% FINDSTR /B %=Must match beginning of line=% "string" %= Search string =% "%%F" %= File to search =% ) 

REM的这种变体似乎是一个安全的方式来使注释部分&签署。

 REM/ REM\ REM: 

尽管@ dbenham的评论,我不能创建任何文件,这将与这些REM变种(我试过REM.batREM;.bat等等)。
REM^<char>之后添加一个空格总是个好主意。

%~的问题无法解决,因为cmd.exe对每行使用多个分析器阶段。
并且在检测到REM的阶段之前的早期阶段(百分比膨胀阶段)检测到%~错误。

但是,根据dbenham的描述,我总是提供内嵌评论的评论

编辑:
我从REM^<char>删除了插入符号,因为这没关系。

通常, REM会对剩余行进行注释,因为批解析器在解析器的阶段2中检测到REM关键字,并且仅切换到专用语法分析程序(REM)。

但是当一个字符被附加到REM ,关键字将不会在阶段2中被检测到。
如果字符是\/;,=+(解析器将在以后删除它并执行一个正常的 REM命令。

这就是为什么命令操作符&&&||| 在这种情况下可以被认可。

为什么rem/ | break rem/ | break失败,但(REM/) | break (REM/) | break作品?
这是因为管道启动了两个独立的cmd子进程。
用括号括起来,该命令将在子进程中第一次被解析。
但没有括号,父进程已经解析了REM/并检查文件是否存在(但不执行)。
但是,当这样的文件存在时,解析器足够聪明,可以删除分隔符字符,并检测到REM是一个内部命令。
这种行为看起来有点奇怪。