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

Variables in Batch Scripts

Learn how Windows batch scripts store, read, and manipulate values using the set command, environment variables, delayed expansion, and substring syntax.

Variables and Control FlowBeginner9 min readJul 10, 2026
Analogies

Understanding Variables in Batch Scripts

A batch variable is a named slot in the environment table that holds a text string, set with the set command and read back with percent signs, as in %VAR%. Unlike typed languages, everything in a .bat file is text: set COUNT=5 stores the two-character string '5', not a number, until an arithmetic command interprets it. Percent-sign expansion happens once, when the command interpreter parses the line, which is why variables behave oddly inside loops without extra handling.

🏏

Cricket analogy: Setting a batch variable is like a cricket scorer chalking the total onto the scoreboard with a command such as SCORE=150-3; the number only changes when the scorer physically rewrites it, just as %VAR% is substituted once when the line is parsed, not continuously.

Setting and Reading Variables

Beyond literal assignment, set /p NAME=Enter your name: prompts the user and stores typed input into NAME, while set /a switches into integer arithmetic mode so set /a TOTAL=A+B actually adds two numeric variables instead of concatenating strings. There must be no spaces around the equals sign in a plain set command, because set VAR = value would create a variable literally named 'VAR ' with a trailing space, a classic beginner bug. Environment variables inherited from Windows itself, like %USERNAME% or %PATH%, are read the same way as ones you define.

🏏

Cricket analogy: Asking a batsman to call yes or no for a run is exactly like set /p RUN=Take the run? , pausing execution until the user provides input, just as a non-striker waits for the calling batsman's decision before moving.

batch
@echo off
set NAME=Batch
set /p AGE=Enter your age:
set /a NEXT_YEAR=AGE+1
echo Hello %NAME%, next year you will be %NEXT_YEAR%

set /a treats its expression as integer math, so set /a X=10/3 yields 3, not 3.33 -- batch has no built-in floating point arithmetic.

Delayed Expansion for Loops

Because %VAR% is expanded once when a whole block (like a for loop or code between parentheses) is parsed, a variable changed inside that block will keep showing its old value if you keep using percent syntax. The fix is setlocal enabledelayedexpansion at the top of the script combined with !VAR! syntax inside the loop body, which re-reads the variable's current value at execution time instead of parse time. This distinction between parse-time and run-time expansion is one of the most common sources of confusing batch bugs, especially inside for and if blocks that span multiple lines.

🏏

Cricket analogy: Reading out the whole day's list of fixtures before the toss even happens is like percent expansion -- the announcer's script was written before anything changed, whereas delayed expansion with !VAR! is like getting a live update read out ball by ball as the score actually changes.

batch
@echo off
setlocal enabledelayedexpansion
set TOTAL=0
for %%N in (1 2 3 4 5) do (
    set /a TOTAL=!TOTAL!+%%N
    echo Running total: !TOTAL!
)
echo Final total: !TOTAL!

Forgetting setlocal enabledelayedexpansion and using %TOTAL% instead of !TOTAL! inside the loop above will print the same stale value (0) on every iteration, because %TOTAL% was already substituted before the loop began executing.

Substring and Replace Syntax

Batch supports lightweight string operations directly in variable expansion syntax: %VAR:~start,length% extracts a substring (negative numbers count from the end), and %VAR:old=new% performs a simple find-and-replace across the whole string. For example, %DATE:~0,4% on a US-locale date pulls out the first four characters, often the year, and %PATH:;=,% would replace every semicolon in PATH with a comma. These operators only work on percent-expanded variables and do not support regular expressions, only literal substring matching.

🏏

Cricket analogy: Trimming a bowler's figures down to just the wickets column from a full scorecard line is like %LINE:~10,2%, pulling out a fixed-width slice of a longer string rather than reading the whole record.

%DATE:~-4% extracts the last four characters of DATE using a negative start offset, a common way to grab a four-digit year regardless of the surrounding date format.

  • Variables are set with set VAR=value and read with %VAR%; there must be no spaces around the equals sign.
  • set /p VAR=prompt reads user input; set /a VAR=expr performs integer arithmetic instead of string concatenation.
  • Percent expansion happens once at parse time, which causes stale values inside for loops and multi-line if blocks.
  • setlocal enabledelayedexpansion plus !VAR! syntax re-reads a variable's live value at execution time inside loops.
  • %VAR:~start,length% extracts a substring; negative numbers count backward from the end of the string.
  • %VAR:old=new% performs a literal, non-regex find-and-replace across the entire variable value.
  • Windows exposes built-in environment variables like %USERNAME%, %PATH%, and %DATE% that are read with the same percent syntax.

Practice what you learned

Was this page helpful?

Topics covered

#Batch#WindowsBatchScriptingStudyNotes#MicrosoftTechnologies#VariablesInBatchScripts#Variables#Scripts#Setting#Reading#StudyNotes#SkillVeris