:EOF 是 Microsoft 在命令 GOTO 的文档中解释的预定义标签。在命令提示符窗口goto /? 中运行的帮助输出也解释了 End Of File 的这个特殊标签。但是这个预定义标签只有在默认启用命令扩展的情况下才受支持。
在命令提示符窗口call /? 中运行的帮助输出,当然还有命令CALL 的文档都解释了goto :EOF 应该用于退出用call :Label 调用的子例程。
子程序只不过是嵌入在当前批处理文件中的另一个批处理文件,使用命令call 调用。如果子程序在批处理文件的末尾,则真正的文件末尾标志着子程序的结束。
但是一个批处理文件中可以有多个子程序。
因此,命令解释器需要一个命令来在命令处理中到达特定行时退出子例程并返回调用命令行。 goto :EOF 和 exit /B 都可以在任何地方使用来退出子例程或退出当前的批处理文件处理。
在有问题的批处理代码中,first goto :EOF 需要退出批处理文件处理,而不会在完成循环后意外落入子程序代码。
提问者批处理代码中的secondgoto :EOF用于退出子程序并在第二行的FOR循环中继续处理。它不退出批处理文件的处理,它只退出子程序的处理。
注意 1: goto EOF 不带冒号要求批处理文件中确实有以:EOF 开头的行,即文件中必须存在标签EOF。 goto :EOF 总是导致退出子程序/批处理并启用命令扩展,即使批处理文件中有标签 EOF,因为一行以 :EOF 开头。
注意 2: 不带参数 /B 的命令 EXIT 始终会导致退出整个命令过程,这与调用层次结构和 Windows 命令处理器的启动方式无关 – 带有参数 /K 到保持 cmd.exe 在打开命令提示符窗口时运行,或在命令处理完成后使用/C 关闭,如双击批处理文件时使用的那样。因此,应在批处理文件中明智地使用不带 /B 的 exit(最好:从不)。
注意 3:exit /B 不适用于禁用命令扩展,如下代码所示:
@echo off
setlocal DisableExtensions
echo Use command exit /B with command extensions disabled.
exit /B
在命令提示符窗口中执行此批处理文件会导致输出错误消息:
系统找不到指定的批次标签-EOF
换句话说,没有额外退出代码的exit /B 与goto :EOF 完全相同,因此也依赖于命令扩展。 exit 不带 /B 不带或带退出代码始终有效。
注意 4: ERRORLEVEL 不受 goto :EOF 影响,但 Microsoft GOTO 文档对此主题保持沉默。 exit /B # 由 Microsoft 将 ERRORLEVEL 设置为 # as documented。 exit /B # 也可以用来代替 goto :EOF 退出子程序,并在调用子程序的命令行上评估特定的退出代码,例如使用运算符 && 或 || 或在调用命令行后的下一个命令if errorlevel X。但是,通常不需要显式退出具有特定退出代码的批处理文件或子例程,因为 goto :EOF 和 exit /B 都不会修改 ERRORLEVEL 的当前值。
注意5:不要在批处理文件中使用goto:EOF或call:Label,命令GOTO和CALL之间没有空格(参数 0)和标签(参数 1)。应始终使用goto :EOF 和call :Label,并在命令和标签之间使用空格作为参数字符串分隔符。原因是goto:EOF 导致尝试首先在当前目录中查找名称为goto: 的文件,然后是名称为goto:EOF 的文件。不正确的命令call:Label 导致搜索名称为call: 的文件,然后搜索名称为call:Label 的文件。对于这两个语法错误的命令,文件系统两次向cmd.exe 返回名称无效。然后cmd.exe 检测冒号作为无效名称的原因,并将命令拆分为命令和标签参数,最后成功运行命令。使用goto :EOF 和call :Label 不会导致任何错误的文件系统访问,因为cmd.exe 会立即将字符串goto 和call 识别为内部命令。
有关ERRORLEVEL 行为的详细信息,请参阅: