Skip to main content

How to Use GOTO for Jumps and Simple Loops in Batch Script

In the world of batch scripting, GOTO is one of the oldest and most fundamental commands for controlling the flow of execution. Unlike a FOR loop that iterates a set number of times, GOTO provides a simple yet powerful way to create unconditional jumps to other parts of your script. It is the primary tool for creating simple loops, handling error conditions, and building menu systems.

This guide will teach you how to define labels and use GOTO to jump to them. You will learn the classic pattern for creating a simple, repeating loop and understand the critical difference between GOTO and CALL for building structured scripts.

What is GOTO?

The GOTO command tells the cmd.exe interpreter to immediately stop executing commands sequentially and to jump to a specific line in the script marked by a label. This allows you to create non-linear execution paths, which are essential for loops and conditional logic.

The Core Components: GOTO and Labels (:MyLabel)

Using GOTO is a two-part process:

  1. Define a Label: A label is a line in your script that starts with a colon (:) followed by a name. The name can be any string without spaces. :MyLoopStart :ErrorHandler :MainMenu
  2. Use GOTO to Jump: The command GOTO MyLabel (without the colon) tells the script to find the corresponding label and continue execution from there.

Basic Example: A Simple Unconditional Jump

This script demonstrates the most basic use of GOTO. It is used here to skip over a block of code.

@ECHO OFF
ECHO This is the first line.
ECHO Now, we will jump over the next section.
GOTO :Skip

REM --- This block of code will NEVER be executed ---
ECHO You will not see this message.
ECHO Or this one.
REM --- End of skipped block ---

:Skip
ECHO.
ECHO We have arrived at the ':Skip' label.
ECHO The script continues from here.

Output:

This is the first line.
Now, we will jump over the next section.

We have arrived at the ':Skip' label.
The script continues from here.

Creating a Simple Loop with GOTO

The most common use for GOTO is to create a loop by jumping backwards to a label that has already been executed. This, combined with an IF statement, allows you to create a loop that runs until a condition is met.

This script creates a simple counter that loops 5 times.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "count=0"

:MyLoop
SET /A "count+=1"
ECHO This is iteration number !count!.

REM --- The Exit Condition ---
IF !count! EQU 5 (
ECHO Reached the limit. Exiting the loop.
GOTO :EndOfLoop
)

REM --- Jump back to the start of the loop ---
GOTO :MyLoop

:EndOfLoop
ECHO.
ECHO The loop has finished.
ENDLOCAL

Common Pitfalls and How to Solve Them

The Danger of Infinite Loops

This is the biggest risk when using GOTO. If you create a loop but forget to include an exit condition (an IF statement that eventually jumps out of the loop), your script will run forever and will have to be manually terminated (with Ctrl+C).

Solution: Always double-check your GOTO loops. Ensure that there is a logical condition inside the loop that will eventually be met, allowing the script to GOTO a label outside the loop.

GOTO vs. CALL: A Critical Distinction

While both commands jump to a label, their behavior is fundamentally different.

  • GOTO is a one-way trip. The script jumps to the label and forgets where it came from.
  • CALL is a round trip. The script jumps to a label (a subroutine) and, when it's done, it returns to the line after the CALL.

Solution: Use GOTO for simple loops and for jumping to error handlers. Use CALL when you are creating reusable functions or subroutines that need to be executed from multiple places in your script.

The Special :EOF Label

:EOF is a special, built-in label that means "End Of File."

  • GOTO :EOF is the standard way to exit a script or subroutine cleanly. When used inside a subroutine called with CALL, it returns to the caller. When used in the main script body, it terminates the script. This is often better than using EXIT because it doesn't close the cmd.exe window.

Practical Example: A "Retry on Failure" Loop

This is a perfect real-world use case for a GOTO loop. The script attempts to connect to a server. If the connection fails, it waits a few seconds and tries again, up to a maximum number of attempts.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "Server=a-real-server.com"
SET "MaxAttempts=3"
SET "attempts=0"

ECHO --- Checking connection to %Server% ---

:PingLoop
SET /A "attempts+=1"
ECHO.
ECHO Attempt !attempts! of %MaxAttempts%...
PING -n 1 "%Server%" > NUL

IF !ERRORLEVEL! EQU 0 (
ECHO [SUCCESS] Server is online!
GOTO :End
)

ECHO [FAILURE] Server is offline.
IF !attempts! GEQ %MaxAttempts% (
ECHO Maximum attempts reached. Aborting.
GOTO :End
)

ECHO Waiting 5 seconds before retrying...
TIMEOUT /T 5 > NUL
GOTO :PingLoop

:End
ECHO.
ECHO --- Script finished ---
ENDLOCAL

Conclusion

The GOTO command is a fundamental tool for controlling the execution flow in batch scripts. While it can lead to messy "spaghetti code" if overused, it is the standard and necessary command for creating simple loops and handling conditional jumps.

Key takeaways:

  • Define a jump destination with a :Label.
  • Jump to that destination with GOTO Label.
  • Create a loop by placing a label at the top and a GOTO at the bottom.
  • Always include an IF condition with a GOTO to an exit label to prevent infinite loops.
  • Use GOTO :EOF to cleanly end your script or return from a subroutine.