-
In the world of batch scripting, GOTO and Labels offer an old-school but direct way to control execution flow, similar to jumping to a bookmark in a document.
-
While modern languages use functions and loops to structure logic, batch scripting still leans heavily on
GOTOfor simple jumps, error handling, or breaking out of linear execution paths.-
GOTOis a command that jumps to a labeled point in the script. -
A Label is a marker defined using a colon
:followed by the label name.Think of
GOTOas saying: "skip ahead and start running from here."
-
-
:myLabelLabels must start with a colon, cannot contain spaces, and are case-insensitive.
-
GOTO myLabelDo not prefix the label name in
GOTOwith a colon — just use the name.@ECHO OFF ECHO This runs first GOTO skip ECHO This will never be seen :skip ECHO Now in the 'skip' section
Output:
This runs first Now in the 'skip' section
-
Although batch supports
FORloops, you can simulate loops usingGOTO:@ECHO OFF SET COUNT=1 :loop IF %COUNT% GTR 5 GOTO end ECHO Iteration: %COUNT% SET /A COUNT+=1 GOTO loop :end ECHO Done!
Here,
GOTO loopcreates a classic "while-like" loop.
-
Batch executes code linearly, so you may want to skip optional sections:
@ECHO OFF SET MODE=release IF "%MODE%"=="debug" GOTO debug ECHO Running in release mode GOTO end :debug ECHO Debugging info here :end ECHO Script complete
-
Although batch doesn’t have functions, you can simulate them using
CALLwith labels:@ECHO OFF CALL :sayHello John CALL :sayHello Alice GOTO :eof :sayHello ECHO Hello, %1! GOTO :eof
Here,
:eofis a special built-in label that means “return to caller” when used withCALL.
-
:EOFis a reserved label in CMD. -
Using
GOTO :EOFmeans "exit current script or subroutine". -
It is useful for returning from a function or exiting early.
IF "%1"=="" GOTO :EOF
⚠ You don’t define
:EOF— CMD knows it automatically.
-
Be careful:
GOTOcan create infinite loops if not properly guarded.:loop ECHO Looping... GOTO loop
Terminate manually with
CTRL+Cif needed.
-
Unlike structured languages, batch does not support nested labels.
All labels exist in a flat namespace.
This will not work as intended:
:start ECHO Outside :inner ECHO Inside
Instead, use unique labels like
:inner_start,:inner_endif you need segmentation.
-
You can’t
GOTOinto another.batfile. Each batch file runs in its own context. To jump between scripts, useCALL:CALL other_script.bat
| Practice | Reason |
|---|---|
Avoid overusing GOTO |
Leads to unreadable “spaghetti code” |
Use CALL :label for reuse |
Allows simulating reusable functions |
Use :EOF for clean exits |
Safer than jumping to arbitrary :end labels |
| Name labels clearly | Improves navigation and maintainability |
-
Menu System
@ECHO OFF :menu ECHO 1. Say Hello ECHO 2. Say Goodbye ECHO 3. Exit SET /P CHOICE=Enter your choice: IF "%CHOICE%"=="1" GOTO hello IF "%CHOICE%"=="2" GOTO goodbye IF "%CHOICE%"=="3" GOTO end GOTO menu :hello ECHO Hello there! GOTO menu :goodbye ECHO Goodbye! GOTO menu :end ECHO Exiting...
Use EXIT /B to stop script execution inside a function:
:something
ECHO Doing something...
EXIT /B 0| Command | Description |
|---|---|
:label |
Marks a jump target |
GOTO label |
Jumps to that label |
CALL :label |
Simulates a function call with return capability |
GOTO :EOF |
Exits current context or subroutine cleanly |