为了账号安全,请及时绑定邮箱和手机立即绑定

(Windows批处理)如果块的行为非常奇怪,请转到其中

/ 猿问

(Windows批处理)如果块的行为非常奇怪,请转到其中

123456qqq 2019-10-21 12:45:28

如果我使用以下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行,它会给出我期望的输出。该echo quux行不应该exectuted,所以为什么goto语句的存在导致这样的事情发生?


更新:对于它的价值,这里有一个替代方法可以正确地实现我最初的意图:


goto BEGIN


:doit

    echo bar

    goto asdf

    :asdf

    echo baz

    goto :EOF


:BEGIN


echo foo

if 1 == 1 (

    call :doit

) else (

    echo quux

)

但是,这不能回答我的原始问题。


查看完整描述

3 回答

?
慕哥6287543

CALL或GOTO的目标绝对不能在括号内的block语句内。可以做到,但是如您所见,结果可能不会是您想要的。


在处理任何IF(...)ELSE(...)结构之前,先将其解析并加载到内存中。换句话说,在逻辑上将其视为一行代码。解析后,CMD.EXE期望从IF / ELSE构造后的下一行开始继续解析。


在解析阶段之后,将从内存执行复杂命令。正确处理了IF子句,并正确跳过了ELSE子句。但是,如果在IF(true)子句中执行GOTO :asdf,则CMD.EXE dutifly开始扫描标签。它从IF / ELSE的末尾开始,然后扫描到文件的底部,然后循环回到顶部,然后进行扫描,直到找到标签为止。标签恰好在您的IF子句中,但是标签扫描程序对此细节一无所知。因此,当复杂命令从内存中完成执行时,批处理将从标签恢复,而不是从复杂IF / ELSE的末尾开始。


因此,此时批处理程序可以看到并执行接下来的几行


    echo baz

) else (

    echo quux

)

baz被回显,quux也被回显。但是您可能会问:“为什么不) else (和/或)生成语法错误,因为它们现在不平衡并且不再作为较大的IF语句的一部分进行解析?


那是因为如何)处理。


如果遇到打开的(活动时间),则将)按您期望的方式处理。


但是,如果解析器期望一个命令并)在没有活动的open时找到一个(,则将)忽略,并且将忽略该行其余部分的所有字符!)现在有效地充当REM语句。


查看完整回答
反对 回复 2019-10-21
?
慕的地8271018

括号内的所有内容都被视为一条直线,只需单击即可处理,解释和执行。您的脚本到达goto asdf并跳出该块/行。在标签上:asdf,没有括号,因此它开始逐行读取行。它到达else,但是if之间没有任何关系:asdf,else因此忽略它。


为防止出现此类问题,我始终使用goto或callon if和for语句,而不是块。这样可以解决更多goto语句的问题,也可以解决很多变量的问题。


使用方法goto:


echo foo

if 1 == 1 goto bar

echo quux

goto nextbit


:bar

echo bar

goto asdf

:asdf

echo baz


:nextbit

:: more script...

或使用call:


echo foo

if 1 == 1 (call :bar) else (call :quux)

:: more script...

exit /b


:bar

echo bar

goto asdf

:asdf

echo baz

exit /b


:quux

echo quux

exit /b


查看完整回答
反对 回复 2019-10-21
?
跃然一笑

在这种情况下,事实证明这与IF语句内部不良的嵌套和循环结构有关,如上文https://stackoverflow.com/users/1012053/dbenham所述。


就是说,由于这个问题,我想出了另一个类似的考虑...请在此处查看以下问题和后续解决方案: 从批处理脚本行'if exist [file](。 ..


解决方案只是在IF语句块内的ECHO行上处理'('和')'。


关键是,在对IF(可能是FOR)语句进行故障排除时,请考虑将特殊字符视为问题的可能根源。


高温超导


查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信