100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Batch

Batch Script Syntax Basics

The core syntax rules of batch scripting: variables, delayed expansion, conditionals, and loops.

FoundationsIntermediate9 min readJul 10, 2026
Analogies

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.

batch
@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

Was this page helpful?

Topics covered

#Batch#WindowsBatchScriptingStudyNotes#MicrosoftTechnologies#BatchScriptSyntaxBasics#Script#Syntax#Variables#Control#StudyNotes#SkillVeris