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

Batch Script Arguments

Learn how Windows Batch scripts read command-line arguments using positional parameters, SHIFT, and path modifiers like %~dp0.

Advanced Batch ScriptingBeginner8 min readJul 10, 2026
Analogies

Reading Command-Line Arguments

When a batch file is invoked as script.bat first second third, the tokens after the script name are available inside the script as %1, %2, %3, and so on, with %0 always referring to the script's own invocation path rather than an argument. %* is a shortcut that expands to all arguments at once as a single space-separated string, which is convenient for simply forwarding every argument to another command without knowing in advance how many were passed. Unlike arrays in other languages, there is no direct way to ask 'how many arguments were passed' as a single count; scripts instead detect the end of the argument list by checking whether the next positional parameter expands to an empty string.

🏏

Cricket analogy: It is like a team sheet where position 1 is always the opening batsman, position 2 the other opener, and so on, while the 'squad list' as a whole (like %*) is the complete roster announced together rather than checked player by player.

SHIFT and Looping Over an Unknown Number of Arguments

Because %1 through %9 only cover the first nine positional parameters directly, scripts that need to process an arbitrary, unknown number of arguments use the SHIFT command inside a loop: SHIFT moves every positional parameter down by one, so what was %2 becomes %1, what was %3 becomes %1's new %2, and so on, letting a single :loop label repeatedly process %1 and then SHIFT until %1 expands to empty. This pattern is the standard idiom for batch files that accept a variable-length file list or option flags, and it pairs naturally with IF "%1"=="" GOTO :done as the loop's termination test, since checking for an empty string is the only reliable way to detect that all arguments have been consumed.

🏏

Cricket analogy: It is like a bowling rotation where after each over, the next bowler in line effectively becomes 'up now', and the captain just keeps calling on 'whoever is next' until the over allocation for the innings runs out.

batch
@echo off
:loop
IF "%~1"=="" GOTO :done
echo Processing argument: %~1
SHIFT
GOTO :loop
:done
echo All arguments processed.

Useful Parameter Modifiers Like %~dp0

Beyond quote-stripping with %~1, batch supports a family of modifiers that decompose a path argument into its components: %~dp0 gives the drive and directory of the currently running script (commonly used to build paths relative to the script's own location regardless of the caller's working directory), %~nx1 gives just the filename and extension of the first argument, and %~f1 expands it to a fully qualified absolute path. These modifiers can also be combined, like %~dpnx1 for the full path, and they are essential for writing scripts that behave predictably no matter which directory they're launched from, since the default working directory a script sees is whatever directory the user happened to be in when they ran it, not the script's own folder.

🏏

Cricket analogy: It is like a ground announcer always knowing the stadium's own fixed address (%~dp0-equivalent) regardless of which city the visiting team traveled from, versus needing to look up just the visiting team's home city name (%~nx1-equivalent) separately.

%~dp0 is the standard way to make a script self-locating: place it at the top as SET SCRIptDir=%~dp0, then reference %SCRIPTDIR%config.ini instead of a hardcoded path, so the script works correctly even when double-clicked from a completely different working directory.

%~dp0 always includes a trailing backslash, so concatenating it with a filename should NOT add another backslash (%~dp0config.ini is correct, %~dp0\config.ini would produce a double backslash which usually still works but is inconsistent and can break in edge cases with UNC paths).

  • Positional parameters %1 through %9 hold the arguments passed to a script, in order; %0 is the script's own path.
  • %* expands to all arguments at once as a single string, useful for forwarding them unmodified.
  • There is no direct 'argument count' variable; scripts detect the end of arguments by testing for an empty %1.
  • SHIFT moves every positional parameter down by one slot, enabling loops over an unbounded argument list.
  • IF "%~1"=="" GOTO :done is the standard loop-termination test when processing shifted arguments.
  • %~dp0 gives the running script's own drive and directory, useful for building self-relative paths.
  • Modifiers like %~nx1, %~f1, and %~dpnx1 decompose or expand a path argument into useful components.

Practice what you learned

Was this page helpful?

Topics covered

#Batch#WindowsBatchScriptingStudyNotes#MicrosoftTechnologies#BatchScriptArguments#Script#Arguments#Reading#Command#StudyNotes#SkillVeris