Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
476 views
in Technique[技术] by (71.8m points)

batch file - Where does GOTO :EOF return to?

I'm trying to understand where in the code exactly does GOTO :EOF return to?

Here is the code:

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
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

:EOF is a predefined label as Microsoft explains in documentation for command GOTO. The help output by running in a command prompt window goto /? explains also this special label for End Of File. But this predefined label is supported only with command extensions being enabled as by default.

The help output by running in a command prompt window call /? and of course also the documentation for command CALL explain both that goto :EOF should be used to exit a subroutine called with call :Label.

A subroutine is nothing else than another batch file embedded within current batch file called with command call. If the subroutine is at end of the batch file, real end of file marks the end of the subroutine.

But there can be multiple subroutines in a batch file.

So a command is needed for command interpreter to exit the subroutine on reaching a specific line in command processing and go back to the calling command line. goto :EOF as well as exit /B can?be both used everywhere to either exit a subroutine or exit the current batch file processing.

In batch code in question the first goto :EOF is needed to exit batch file processing without an unwanted fall through to the subroutine code after finishing the loop.

The second goto :EOF in batch code of questioner is for exiting the subroutine and continue processing in FOR loop in second line. It does not exit processing of the batch file, it exits only the processing of the subroutine.

Note 1: goto EOF without a colon requires that there is really a line starting with :EOF in the batch file, i.e. the label EOF must exist in the file. goto :EOF always results in exiting subroutine/batch processing with command extensions enabled even if there is a label EOF in the batch file because of a line starting with :EOF.

Note 2: Command EXIT without parameter /B results always in exiting entire command process independent on calling hierarchy and independent on how the Windows command processor was started – with parameter /K to keep cmd.exe running as used when opening a command prompt window or with /C to close after command processing finished as used on double clicking a batch file. Therefore exit without /B should be used wisely in a batch file (best: never).

Note 3: exit /B does not work with command extensions disabled as demonstrated by this code:

@echo off
setlocal DisableExtensions
echo Use command exit /B with command extensions disabled.
exit /B

Executing this batch file from within a command prompt window results in output of the error message:

The system cannot find the batch label specified - EOF

In other words exit /B without an additional exit code is exactly like goto :EOF and depends therefore also on command extensions. exit without /B without or with an exit code works always.

Note 4: ERRORLEVEL is not affected by goto :EOF, but the Microsoft GOTO documentation is mute on this topic. exit /B # sets ERRORLEVEL to # as documented by Microsoft. exit /B # can be also used instead of goto :EOF to exit a subroutine with a specific exit code evaluated on the command line calling the subroutine like on using the operators && or || or on next command after calling command line with if errorlevel X. However, explicitly exiting a batch file or a subroutine with a specific exit code is usually not needed as neither goto :EOF nor exit /B modify the current value of?ERRORLEVEL.

Note 5: Do not use goto:EOF or call:Label in a batch file with no space between command GOTO respectively CALL (argument 0) and the label (argument 1). There should be always used goto :EOF and call :Label with a space as argument string separator between command and label. The reason is that goto:EOF results in the attempts to find in current directory first a file with name goto: and next a file with name goto:EOF. The incorrect command call:Label results in searching for a file with name call: and next with name call:Label. The file system returns for both syntactically wrong commands twice to cmd.exe that the name is invalid. Then cmd.exe detects the colon as reason for the invalid name and splits the command up into command and label argument and finally runs the command with success. The usage of goto :EOF and call :Label does not cause any wrong file system accesses as cmd.exe immediately recognizes the string goto respectively call as internal command.

For details on ERRORLEVEL behavior see:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...