批处理文件 – (Windows批处理)如果块中的Goto行为非常奇怪

如果我采取以下 Windows批处理代码段并运行它:
echo foo
if 1 == 1 (
    echo bar
    goto asdf
    :asdf
    echo baz
) else (
    echo quux
)

我期望的输出是:

foo
bar
baz

但是我得到:

foo
bar
baz
quux

如果我注释了goto asdf行,它给出了我期望的输出.回声曲线不应该被引导出来,那么为什么goto的存在会导致这种情况呢?

更新:为什么值得,这是一个解决方法,正确地做了我原来的意图:

goto BEGIN

:doit
    echo bar
    goto asdf
    :asdf
    echo baz
    goto :EOF

:BEGIN

echo foo
if 1 == 1 (
    call :doit
) else (
    echo quux
)

但是,这并不能解答我原来的问题.

CALL或GOTO的目标不应位于括号内的块语句中.可以做到这一点,但是如你所见,结果可能不会是你想要的.

整个IF(…)ELSE(…)构造被解析并加载到内存中,然后再处理它们.换句话说,它被逻辑地视为一行代码.解析后,CMD.EXE期待从IF / ELSE结构之后的下一行开始继续解析.

解析阶段后,复制命令从内存中执行.正确处理IF子句并正确跳过ELSE子句.但是在IF(true)子句中,您执行GOTO:asdf,因此CMD.EXE开始扫描标签.它从IF / ELSE的结尾开始,并扫描到文件底部,循环回到顶端,并扫描直到找到标签.标签恰好在您的IF子句中,但标签扫描器对该细节无关.因此,当复杂命令从内存完成执行时,批处理从标签而不是从复合IF / ELSE的结尾继续.

因此,在这一点上,批处理器看到并执行接下来的几行

echo baz
) else (
    echo quux
)

巴兹回应了,也是如此.但是您可能会问:“为什么不”)else(和/或)生成语法错误,因为它们现在不平衡,不再作为较大IF语句的一部分解析?

这是因为如何处理.

如果遇到一个打开(活动的时间),那么)按照你的预期进行处理.

但是,如果解析器期望一个命令,并发现a)当没有活动打开(,那么)将被忽略,并且该行的其余部分上的所有字符都将被忽略!有效地,)现在作为一个REM语句.

相关文章

Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...
Windows文件操作基础代码 Windows下对文件进行操作使用的一段...
Winpcap基础代码 使用Winpcap进行网络数据的截获和发送都需要...
使用vbs脚本进行批量编码转换 最近需要使用SourceInsight查看...