Windows CMD-禁用延迟扩展后,为什么两个感叹号前面的小节都被删除?

时间:2019-07-09 15:50:34

标签: windows batch-file cmd

我试图了解有关Windows CMD解析器如何工作的更多信息。我已经阅读了几篇有关CMD解析器的文章,包括这个one,但是我似乎无法弄清楚为什么当禁用延迟扩展时以下代码中的两个插入符号(^)都被剥离了:

@echo off

setlocal disabledelayedexpansion

set $test_var=This is text with escaped delayed expansion syntax - ^^!$var1^^! and ^^!$var2^^!

echo $test_var = %$test_var%

echo.
pause

我希望运行代码的结果能够产生以下输出:

$test_var = This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!

相反,所有插入符号均被删除:

$test_var = This is text with escaped delayed expansion syntax - !$var1! and !$var2!

通过阅读有关解析器的post,据我了解,阶段2删除了特殊字符,其中包括脱字符号(^)。从我的阅读看来,似乎只应删除一(1)个脱字符。为什么两个插入符都被删除?

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

答案的关键在于,在识别特殊字符之前(第二阶段),出现了正常(%-)扩展(第一阶段)的事实-请参阅已接受的答案到:How does the Windows Command Interpreter (CMD.EXE) parse scripts?


该行中的命令解释器删除了第一个插入符号(^

set $test_var=This is text with escaped delayed expansion syntax - ^^!$var1^^! and ^^!$var2^^!

阶段2完成后,因此^^的每个实例都变成一个文字^。您可以在将@echo off更改为@echo on时证明这一点,以便在执行每个解析的命令行之前,或者在下一行中放置以下命令时(由于用户jeb hint):

rem // This displays the actual content of the variable:
set $test_var

在下一行中

echo $test_var = %$test_var%

移除剩余的插入符号是因为–如前所述– %扩展(第1阶段)首先发生,从而产生了类似命令行的

echo $test_var = This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!

然后进入第2阶段,识别并删除其余的插入符号,得到最终文本

$test_var = This is text with escaped delayed expansion syntax - !$var1! and !$var2!

使用加引号的语法时,您可以在set命令行中保护插入符号(以及其他任何特殊字符),如下所示:

set "$test_var=This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!"

因此您可以保存一层escaping。但是,这仅在启用command extensions时有效,但这仍然是命令解释器的默认设置。

但是对于echo命令行,您不能使用这种方法,因为引号也被返回了。


我发现您使用echo.输出空行。您最好使用echo/echo((请参阅外部资源ECHO. FAILS to give text or blank line - Instead use ECHO/找出原因)。


顺便说一句,由于您禁用了delayed expansion,因此显示的文字与实际情况不符。