Batch Script Syntax Basics
Batch scripting syntax follows a few consistent rules: one command per line, with cmd.exe treating whitespace as the separator between a command and its arguments. Commands themselves are case-insensitive, so ECHO, echo, and Echo all behave identically. Certain characters have special meaning to the command interpreter -- %, ^, &, |, <, and > -- and need to be escaped with the caret (^) when you want them treated as literal text rather than as syntax.
Cricket analogy: Batch syntax being case-insensitive is like an umpire accepting 'OUT' or 'out' or 'Out' as the same signal -- cmd.exe doesn't care about capitalization, only the word itself.
Variables
Variables are created with the set command, for example set name=Alice, and read by wrapping the name in percent signs: %name%. Windows also exposes built-in environment variables the same way, like %PATH% or %USERNAME%. There's a catch inside loops and IF blocks, though: %VAR% is expanded once, when the whole parenthesized block is parsed, so changes made to a variable inside the block won't show up if you keep reading it as %VAR% within that same block. To see live updates, you enable delayed expansion with setlocal enabledelayedexpansion and reference the variable as !VAR! instead.
Cricket analogy: Delayed expansion is like a scorer who only updates the printed scoreboard once per over instead of ball-by-ball -- you need a special live mode (enabledelayedexpansion) to see the score change within the over itself.
Control Flow: IF and GOTO
Batch offers IF for conditional logic -- comparing strings or numbers, using the /I switch for case-insensitive string comparisons, and checking %ERRORLEVEL% to see whether the previous command succeeded. There's no true function syntax, but GOTO :label lets you jump execution to any labeled point in the script, and CALL :label combined with goto :eof at the end of that section emulates a subroutine: control returns to the line right after the CALL once the labeled section finishes.
Cricket analogy: Using GOTO to jump to a label is like a coach signaling 'go straight to Plan B field setting' mid-over, skipping the usual progression and jumping directly to a named strategy.
@echo off
setlocal enabledelayedexpansion
set count=0
for /l %%i in (1,1,5) do (
set /a count+=1
echo Iteration number: !count!
)
if %count% EQU 5 (
echo Loop finished successfully.
) else (
echo Something went wrong.
)
goto :end
:printExtra
echo This label is only reached via GOTO.
goto :eof
:end
echo Script complete.CALL :label lets you treat a label like a subroutine -- it jumps to the label and, when the script reaches goto :eof or the end of the file, execution returns to the line right after the CALL. This is the closest batch gets to a real function.
Loops with FOR
FOR loops come in several flavors. for /l %%i in (1,1,10) do ... iterates through a numeric range (from 1 to 10, stepping by 1). for /f is used to parse text output line by line, whether from a file or from the output of another command -- extremely useful for processing log files or command results. for /d iterates over directories matching a pattern instead of files. Note that at the command line you use a single percent sign like %i, but inside a saved .bat file you must double it to %%i.
Cricket analogy: A for /l loop counting from 1 to 20 is like a bowler running through a fixed 20-over spell, delivering one action per iteration until the count is exhausted.
- Batch commands are case-insensitive and are executed one per line, top to bottom, unless redirected.
- Use set VAR=value to create a variable and %VAR% to read it outside of loops and conditional blocks.
- Inside FOR loops or IF blocks, use delayed expansion (setlocal enabledelayedexpansion and !VAR!) to see updated variable values in real time.
- IF supports string and numeric comparisons, the /I switch for case-insensitive checks, and ERRORLEVEL checks for command success/failure.
- GOTO :label jumps execution to a named label anywhere in the script, skipping everything in between.
- CALL :label combined with goto :eof emulates a subroutine, returning control after the CALL when finished.
- FOR has several forms: for /l for numeric ranges, for /f for parsing text/file/command output, and for /d for directories.
Practice what you learned
1. Why does %VAR% often fail to show updated values inside a FOR loop?
2. What must you enable to make !VAR! syntax work?
3. What is the standard way to emulate a subroutine in batch scripting?
4. Which FOR variant is used to parse the line-by-line output of another command?
5. Are batch commands like ECHO case-sensitive?
Was this page helpful?
You May Also Like
What Is Batch Scripting?
An introduction to what Windows batch scripting is, where it came from, and when to use it.
Creating and Running .bat Files
A practical guide to creating .bat files and running them correctly, including passing arguments.
Comments in Batch Files
How to write and use comments in batch files, and why documentation matters for long-lived scripts.
Echo and Output
How ECHO and output redirection let you control exactly what a batch script prints to the console.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics