我试图了解代码在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
答案 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 :EOF
将exit /B #
设置为ERRORLEVEL
as documented。也可以使用#
代替exit /B #
来退出子例程,该子例程使用在命令行上调用的特定退出代码来调用子例程,就像使用运算符goto :EOF
或&&
或在使用||
调用命令行后执行下一个命令。但是,通常不需要显式退出批处理文件或具有特定退出代码的子例程,因为if errorlevel X
和goto :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)
由于GOTO
和CALL
使用相同的功能来查找标签,因此您也可以选择通过:EOF
访问CALL
:
CALL ::EOF
与GOTO
相同(当CALL
带有附加分号时),实际文件结尾将是脚本流的首选。如果您使用 EOF 定义了自己的标签\功能,则可以使用单个分号来访问它。
尽管调用:EOF
并没有太多用处-您不能在文件末尾放置代码,因此该行实际上什么都不做(尽管这会在分析文件末尾时影响性能) 。由于GOTO
和EXIT /B
在没有启用扩展名的情况下无法工作。