(Windows批处理)转到内如果块的行为很奇怪 [英] (Windows batch) Goto within if block behaves very strangely

查看:92
本文介绍了(Windows批处理)转到内如果块的行为很奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我采取以下Windows批处理code段,并运行它:

If I take the following Windows batch code snippet and run it:

echo foo
if 1 == 1 (
    echo bar
    goto asdf
    :asdf
    echo baz
) else (
    echo quux
)

我期望的输出是:

The output I would expect is:

foo
bar
baz

而是我得到:

foo
bar
baz
quux

如果我注释掉转到航空自卫队行,它给了我期望的输出。在回声QUUX 行不应该exectuted,那么为什么是后藤的存在导致这样的事情发生?

If I comment out the goto asdf line, it gives the output I expect. The echo quux line should never be exectuted, so why is the existence of the goto causing that to happen?

更新:对于它的价值,下面是正确做什么,我本来想一个解决办法:

UPDATE: For what it's worth, here's a workaround that correctly does what I originally intended:

goto BEGIN

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

:BEGIN

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

不过,这并没有回答我原来的问题。

However, this doesn't answer my original question.

推荐答案

CALL或GOTO的目标不应该是括号内的块语句内。这是可以做到的,但你看,结果可能不会是你想要的。

The target of a CALL or GOTO should never be inside a block statement within parentheses. It can be done, but as you see, the results are probably not going to be what you want.

整个中频(...)ELSE(...)构建体的任何处理前解析并装入内存。在其它字,它在逻辑上视为code的一行。它分析后,CMD.EXE期待恢复解析开始与IF / ELSE构造之后的下一行。

The entire IF (...) ELSE (...) construct is parsed and loaded into memory before any of it is processed. In other-words, it is logically treated as one line of code. After it is parsed, CMD.EXE is expecting to resume parsing starting with the next line after the IF/ELSE construct.

解析阶段后,将复杂的命令,从存储器执行。 IF子句正确处理和ELSE子句正确跳过。但IF(真)子句中,您执行 GOTO:ASDF ,所以CMD.EXE dutifly开始扫描的标签。它开始在IF / ELSE并扫描到文件的底部,循环回到顶端的末端,并扫描直到它找到的标签。标签恰好是你的IF子句中,但标签扫描器一无所知的细节。因此,当复杂的命令完从存储器执行,批处理从标签而不是从复杂的端部恢复的IF / ELSE

After the parse phase, the complex command is executed from memory. The IF clause is processed properly and the ELSE clause is skipped properly. BUT within the IF (true) clause, you perform a GOTO :asdf, so CMD.EXE dutifly begins scanning for the label. It starts at the end of the IF/ELSE and scans to the bottom of the file, loops back to the top, and scans until it finds the label. The label happens to be within your IF clause, but the label scanner knows nothing about that detail. So when the complex command finishes executing from memory, batch processing resumes from the label instead of from the end of the complex IF/ELSE.

所以在这一点批处理器看见并执行接下来的几行

So at this point the batch processor sees and executes the next few lines

    echo baz
) else (
    echo quux
)

巴兹相呼应,所以是QUUX。但你可能会问:为什么不)否则(和/或生成语法错误,因为它们是现在不平衡,不再解析为较大的IF语句的一部分?

baz is echoed, and so is quux. But you might ask, "Why doesn't ) else ( and/or ) generate a syntax error since they are now unbalanced and no longer parsed as part of the larger IF statement?

这是因为如何的处理。

如果有打开的激活时遇到,那么如你所愿的处理。

If there is an open ( active when ) is encountered, then the ) is processed as you would expect.

但如果解析器期待一个命令,并找到一个)时,没有主动打开 ,那么被忽略,在该行的其余所有字符都被忽略!有效的现在充当一个REM语句。

But if the parser is expecting a command and finds a ) when there is not an active open (, then the ) is ignored and all characters on the remainder of the line are ignored! Effectively the ) is now functioning as a REM statement.

这篇关于(Windows批处理)转到内如果块的行为很奇怪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆