GOTO:EOF返回哪里?

时间:2016-05-29 23:28:00

标签: batch-file for-loop

我试图了解代码在GOTO :EOF返回的确切位置?

以下是代码:

SET count=1 
FOR /f "tokens=*" %%G IN (somefile.txt) DO (call :subroutine "%%G") 
GOTO :EOF

:subroutine  
echo %count%:%1  
set /a count+=1  
GOTO :EOF

4 个答案:

答案 0 :(得分:50)

:EOF是Microsoft在命令GOTO的文档中解释的预定义标签。通过在命令提示符窗口goto /?中运行帮助输出,还解释了文件结尾的此特殊标签。但是,只有在默认情况下启用命令扩展时才支持此预定义标签。

通过在命令提示符窗口call /?中运行帮助输出,当然还有命令CALL的文档解释了goto :EOF应该用于退出用{{调用的子例程1}}。

子程序只是嵌入在使用命令call :Label调用的当前批处理文件中的另一个批处理文件。如果子例程位于批处理文件的末尾,则文件的真实结束标记子例程的结束。

但是批处理文件中可以有多个子程序。

因此命令解释器需要一个命令来在命令处理中到达特定行时退出子例程并返回到调用命令行。 call以及goto :EOF可以在任何地方用于退出子例程或退出当前批处理文件处理。

在相关的批处理代码中,退出批处理文件处理需要第一个 exit /B,而不会在完成循环后不必要地落入子程序代码。

提问者批处理代码中的第二 goto :EOF用于退出子程序,并在第二行的 FOR 循环中继续处理。它不会退出批处理文件的处理,它只退出子程序的处理。

注1: goto :EOF没有冒号要求批处理文件中确实存在以goto EOF开头的行,即跳转标签:EOF必须存在于文件中。 EOF始终导致退出子例程/批处理,并启用命令扩展,即使批处理文件中存在标签goto :EOF,因为行以EOF开头。

注意2:没有参数:EOF的命令EXIT总是在退出整个命令进程中独立于调用层次结构而独立于Windows命令处理器的启动方式 - 使用参数在打开命令提示符窗口时,/B 保持 /K正在运行,或者在命令处理完成后使用cmd.exe关闭双击批处理文件。因此,应在批处理文件中明智地使用/C而不是exit(最好:从不)。

注3: /B无法使用此代码所示的命令扩展名停用:

exit /B

在命令提示符窗口中执行此批处理文件会导致输出错误消息:

  

系统找不到指定的批次标签 - EOF

换句话说,没有额外退出代码的@echo off setlocal DisableExtensions echo Use command exit /B with command extensions disabled. exit /B exit /B完全相同,因此也依赖于命令扩展。没有goto :EOF没有或有退出代码的exit始终有效。

注4: /B不受ERRORLEVEL影响,但Microsoft GOTO文档对此主题无效。 Microsoft goto :EOFexit /B #设置为ERRORLEVEL as documented。也可以使用#代替exit /B #来退出子例程,该子例程使用在命令行上调用的特定退出代码来调用子例程,就像使用运算符goto :EOF&&或在使用||调用命令行后执行下一个命令。但是,通常不需要显式退出批处理文件或具有特定退出代码的子例程,因为if errorlevel Xgoto :EOF都不会修改exit /B的当前值。

有关ERRORLEVEL行为的详细信息,请参阅:

答案 1 :(得分:6)

GOTO :EOF 在功能上等同于exit /B,但这两种形式仅在启用扩展时有效。这一点的测试非常简单:

setlocal DisableExtensions
goto :EOF

比较以前的代码与此代码:

setlocal DisableExtensions
exit /B

这意味着GOTO :EOF会返回同一点,其中exit /B会返回。

答案 2 :(得分:0)

:eof 表示“文件结尾”。它用于使脚本完成而不执行以下任何命令。

答案 3 :(得分:0)

由于GOTOCALL使用相同的功能来查找标签,因此您也可以选择通过:EOF访问CALL

CALL ::EOF

GOTO相同(当CALL带有附加分号时),实际文件结尾将是脚本流的首选。如果您使用 EOF 定义了自己的标签\功能,则可以使用单个分号来访问它。

尽管调用:EOF并没有太多用处-您不能在文件末尾放置代码,因此该行实际上什么都不做(尽管这会在分析文件末尾时影响性能) 。由于GOTOEXIT /B在没有启用扩展名的情况下无法工作。