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
At the end of your subroutine, you can jump to the end of the batch file (so that execution falls off the end) by doing a goto :eof . In other words, goto :eof is the return statement for batch file subroutines.
In a nutshell, the goto command is a way to control the flow of a batch file. Typically, when you execute a batch file, the script executes from top to bottom following each line. But sometimes, you need the script to start executing at a different place in the script. The goto command is perfect for this.
For example: goto:EOF . You can use spaces in the label parameter, but you can't include other separators (for example, semicolons (;) or equal signs (=)).
Usage: GOTO can only be used in batch files. After a GOTO command in a batch file, the next line to be executed will be the one immediately following the label. The label must begin with a colon [:] and appear on a line by itself, and cannot be included in a command group.
: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
without or with an exit code works always, but outputs an error message with command extensions disabled as demonstrated by this code:
@echo off setlocal DisableExtensions echo Use command exit /B with command extensions disabled. exit /B 5 echo This line is not processed anymore.
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
But the processing of the batch file is exited nevertheless with the exit code value 5
as it can be seen on running next in same command prompt window echo ERRORLEVEL is: %ERRORLEVEL%
which outputs: ERRORLEVEL is: 5
It looks like there is assigned first the specified exit code value 5
to the dynamic variable ERRORLEVEL
on using exit /B 5
and next is executed goto :EOF
because of option /B
. That fails because of disabled command extensions resulting in the error message and in exiting the batch file processing as it always occurs on a label to go to does not exist in a batch file.
In other words exit /B
without or with an additional exit code always works, but there should be appended 2>nul
to suppress the error message on command extensions disabled, i.e. use exit /B 2>nul
(without exit code) or exit /B 5 2>nul
(with exit code)
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 strings 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:
GOTO :EOF
is functionally equivalent to exit /B
, but both forms only works when Extensions are enabled. The test for this point is very simple:
setlocal DisableExtensions goto :EOF
Compare previous code vs. this one:
setlocal DisableExtensions exit /B
This means that GOTO :EOF
returns to the same point where exit /B
would return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With