我正在尝试使用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.bat
, REM;.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
是一个内部命令。
这种行为看起来有点奇怪。