In Windows, how do you access arguments passed when a batch file is run?
For example, let's say I have a program named hello.bat
. When I enter hello -a
at a Windows command line, how do I let my program know that -a
was passed in as an argument?
This question is related to
windows
batch-file
cmd
parameters
arguments
Batch Files automatically pass the text after the program so long as their are variables to assign them to. They are passed in order they are sent; e.g. %1 will be the first string sent after the program is called, etc.
If you have Hello.bat and the contents are:
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
and you invoke the batch in command via
hello.bat APerson241 %date%
you should receive this message back:
Hello, APerson241 thanks for running this batch file (01/11/2013)
Using parameters in batch files: %0 and %9
Batch files can refer to the words passed in as parameters with the tokens: %0
to %9
.
%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.
parameters passed in on the commandline must be alphanumeric characters and delimited by spaces. Since %0
is the program name as it was called, in DOS %0
will be empty for AUTOEXEC.BAT if started at boot time.
Example:
Put the following command in a batch file called mybatch.bat
:
@echo off
@echo hello %1 %2
pause
Invoking the batch file like this: mybatch john billy
would output:
hello john billy
Get more than 9 parameters for a batch file, use: %*
The Percent Star token %*
means "the rest of the parameters". You can use a for loop to grab them, as defined here:
http://www.robvanderwoude.com/parameters.php
Notes about delimiters for batch parameters
Some characters in the command line parameters are ignored by batch files, depending on the DOS version, whether they are "escaped" or not, and often depending on their location in the command line:
commas (",") are replaced by spaces, unless they are part of a string in
double quotes
semicolons (";") are replaced by spaces, unless they are part of a string in
double quotes
"=" characters are sometimes replaced by spaces, not if they are part of a
string in double quotes
the first forward slash ("/") is replaced by a space only if it immediately
follows the command, without a leading space
multiple spaces are replaced by a single space, unless they are part of a
string in double quotes
tabs are replaced by a single space
leading spaces before the first command line argument are ignored
Use variables i.e. the .BAT
variables and called %0
to %9
@Jon's :parse
/:endparse
scheme is a great start, and he has my gratitude for the initial pass, but if you think that the Windows torturous batch system would let you off that easy… well, my friend, you are in for a shock. I have spent the whole day with this devilry, and after much painful research and experimentation I finally managed something viable for a real-life utility.
Let us say that we want to implement a utility foobar
. It requires an initial command. It has an optional parameter --foo
which takes an optional value (which cannot be another parameter, of course); if the value is missing it defaults to default
. It also has an optional parameter --bar
which takes a required value. Lastly it can take a flag --baz
with no value allowed. Oh, and these parameters can come in any order.
In other words, it looks like this:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
Complicated? No, that seems pretty typical of real life utilities. (git
anyone?)
Without further ado, here is a solution:
@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson
SET CMD=%~1
IF "%CMD%" == "" (
GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=
SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
SHIFT
IF NOT "%ARG%" == "" (
IF NOT "%ARG:~0,2%" == "--" (
SET FOO=%ARG%
SHIFT
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE IF "%PARAM%" == "--bar" (
SHIFT
IF NOT "%ARG%" == "" (
SET BAR=%ARG%
SHIFT
) ELSE (
ECHO Missing bar value. 1>&2
ECHO:
GOTO usage
)
) ELSE IF "%PARAM%" == "--baz" (
SHIFT
SET BAZ=true
) ELSE IF "%PARAM%" == "" (
GOTO endargs
) ELSE (
ECHO Unrecognized option %1. 1>&2
ECHO:
GOTO usage
)
GOTO args
:endargs
ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
ECHO Baz
)
REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof
:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1
Yes, it really is that bad. See my similar post at https://stackoverflow.com/a/50653047/421049, where I provide more analysis of what is going on in the logic, and why I used certain constructs.
Hideous. Most of that I had to learn today. And it hurt.
Source: Stackoverflow.com