How can I pass arguments to a batch file?
Asked Answered
M

20

1436

I need to pass an ID and a password to a batch file at the time of running rather than hardcoding them into the file.

Here's what the command line looks like:

test.cmd admin P@55w0rd > test-log.txt
Morel answered 25/8, 2008 at 18:14 Comment(2)
For "all the rest" see Greg Hegill's comment at how to get batch file parameters from Nth position on?Gellman
I have an environment startup script that will push my username/password into environment variables... so that I don't have to type them out each time... I'm using bash most of the time though (linux, mac and windows), and need to use it for proxy configs in scripts, etc for work.Snake
M
358

Here's how I did it:

@fake-command /u %1 /p %2

Here's what the command looks like:

test.cmd admin P@55w0rd > test-log.txt

The %1 applies to the first parameter the %2 (and here's the tricky part) applies to the second. You can have up to 9 parameters passed in this way.

Morel answered 18/9, 2008 at 12:26 Comment(3)
If you're as dumb as me, your mind was looking for echo %1 %2 and was thrown off by the non cut-and-pasteable simplest case with a @ and a fake-command with params, thinking we'd get fake-command.bat's contents later (in which case, the overcomplicated fake-command.bat might have echo %2 %4 to ignore the param names). Wrong, doofus. TL;DR: Don't be as dumb as me. 1. echo echo %1 %2 > test.bat 2. test word1 word2. 3. Profit.Pocky
Five years later, I'm back reading my comment w/ confusion. Seem to have meant "to create a .bat with two parameters, literally type echo echo %1 %2 > test.bat. The test.bat file will have echo %1 %2 in it (you could've also saved it from a text editor). Now type test word1 word2 to call & see the parameters worked. word1 word2 will be echoed to the command line. (echo %2 %4 would've ignored /u and /p so you could've called test /u word1 /p word2 to get the same result). @ before a cmd in a bat file means the cmd isn't repeated.Pocky
You might want some quote handling/protection too, e.g.: SetLocal Set dbName=%1 Rem dbName If Not Defined dbName Goto SyntaxErr REM Remove all (/any) the quotes Set dbName=%dbName:"=% If "%dbName%" == "" Goto SyntaxErrKelvinkelwen
G
1285

Another useful tip is to use %* to mean "all". For example:

echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*

When you run:

test-command admin password foo bar

The above batch file will run:

fake-command /u admin /p password admin password foo bar

I may have the syntax slightly wrong, but this is the general idea.

Gondi answered 25/8, 2008 at 19:41 Comment(7)
%* actually expands to all parameters regardless of shift. So even after the two shifts you would still have the first two arguments in %*. You can use something like this: #762115 to get a variable that contains everything but the first n parameters.Felisafelise
Please note that %* does not work everywhere! For instance, it does not work with DOSBox 0.73 (maybe this is a bug that should be reported).Calculation
It's not a bug because %* never worked in MS-DOS or Win9x in the first place.Pantywaist
I think shift "pops" the argument from the list. The assumption by OP was that %* would only output the remaining arguments, but it doesn't work that way, as @Felisafelise said.Argyres
This answer is wrong. It actually results in fake-command /u admin /p password admin password foo bar. This was pointed out by @Felisafelise many years ago.Elinoreeliot
The two shifts are pointless in this case. AFTER them %1 would become foo and %2 would become bar but this is not used in any way and %* is not affected by the shift commandZingaro
what does fake-command do or what does it mean ?Triarchy
M
358

Here's how I did it:

@fake-command /u %1 /p %2

Here's what the command looks like:

test.cmd admin P@55w0rd > test-log.txt

The %1 applies to the first parameter the %2 (and here's the tricky part) applies to the second. You can have up to 9 parameters passed in this way.

Morel answered 18/9, 2008 at 12:26 Comment(3)
If you're as dumb as me, your mind was looking for echo %1 %2 and was thrown off by the non cut-and-pasteable simplest case with a @ and a fake-command with params, thinking we'd get fake-command.bat's contents later (in which case, the overcomplicated fake-command.bat might have echo %2 %4 to ignore the param names). Wrong, doofus. TL;DR: Don't be as dumb as me. 1. echo echo %1 %2 > test.bat 2. test word1 word2. 3. Profit.Pocky
Five years later, I'm back reading my comment w/ confusion. Seem to have meant "to create a .bat with two parameters, literally type echo echo %1 %2 > test.bat. The test.bat file will have echo %1 %2 in it (you could've also saved it from a text editor). Now type test word1 word2 to call & see the parameters worked. word1 word2 will be echoed to the command line. (echo %2 %4 would've ignored /u and /p so you could've called test /u word1 /p word2 to get the same result). @ before a cmd in a bat file means the cmd isn't repeated.Pocky
You might want some quote handling/protection too, e.g.: SetLocal Set dbName=%1 Rem dbName If Not Defined dbName Goto SyntaxErr REM Remove all (/any) the quotes Set dbName=%dbName:"=% If "%dbName%" == "" Goto SyntaxErrKelvinkelwen
T
177

If you want to intelligently handle missing parameters you can do something like:

IF %1.==. GOTO No1
IF %2.==. GOTO No2
... do stuff...
GOTO End1

:No1
  ECHO No param 1
GOTO End1
:No2
  ECHO No param 2
GOTO End1

:End1
Tavy answered 25/8, 2008 at 20:3 Comment(3)
What's the significance of dot/period in these equality operations?Assignation
Basically if %1 is empty, this will end up being IF . == . and so the GOTO will happen. We use x here so: IF x%1 == x -> IF x==x -> trueNesselrode
You should aks for what is the value of a "unprovided argument"? Againts what you should check an "unprovided argument"? Then, if you don't have an answer, you should use a trick like the one of the dots. Remember that, like stated here ss64.com/nt/if.html "You can in fact use almost any character for this a '~' or curly brackets, { } or even the number 4, but square brackets tend to be chosen because they don't have any special meaning."Myocardiograph
S
102

Accessing batch parameters can be simple with %1, %2, ... %9 or also %*,
but only if the content is simple.

There is no simple way for complex contents like "&"^&, as it's not possible to access %1 without producing an error.

set  var=%1
set "var=%1"
set  var=%~1
set "var=%~1"

The lines expand to

set  var="&"&
set "var="&"&"
set  var="&"&
set "var="&"&"

And each line fails, as one of the & is outside of the quotes.

It can be solved with reading from a temporary file a remarked version of the parameter.

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt="
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

The trick is to enable echo on and expand the %1 after a rem statement (works also with %2 .. %*).
So even "&"& could be echoed without producing an error, as it is remarked.

But to be able to redirect the output of the echo on, you need the two for-loops.

The extra characters * # are used to be safe against contents like /? (would show the help for REM).
Or a caret ^ at the line end could work as a multiline character, even in after a rem.

Then reading the rem parameter output from the file, but carefully.
The FOR /F should work with delayed expansion off, else contents with "!" would be destroyed.
After removing the extra characters in param1, you got it.

And to use param1 in a safe way, enable the delayed expansion.

Serendipity answered 30/3, 2011 at 22:16 Comment(10)
for /F "tokens=*" %%a in ('echo %*') do set "all_args=%%a"Pow
@KevinEdwards Then try it with one &, your solution works only with simple contentSerendipity
@KevinEdwards I tested it, test.bat ^& and it fails. Only test.bat "&" works, but that wasn't my point. You can't use %*, %1 in a safe way without the REM technicSerendipity
Ah, yes, a caret doesn't escape it properly. You need quotes, which is feasible for all the use cases I've come across. I just wanted to pass it along. Thanks for testing it! Cheers :)Pow
I have a concern about this method (echo-on-and-rem-piped-to-a-file trick): Although batch and cmd.exe don't allow newlines in command arguments, but for shells that allow it when calling the script, the trick breaks. And don't laugh, because PowerShell allow newlines in arguments. Using low-level CreateProcess() function is also possible to make a newline and break it.Cyclosis
@Cyclosis Batch and also cmd.exe allowes both newlines in arguments, but it's tricky. The echo-on-and-rem-redirect-to-a-file trick can also fetch multiline arguments, but that isn't bullet proof, see SO:...multi line text as argument...Serendipity
@Serendipity The SO answer you mentioned does allow multi-line argument parsing, but doesn't protect against command injection from line 2 and onward. I fear there will be no true bullet-proof solution until there's an extension syntax (e.g. !1! !2! or !!1 !!2) that can truly delay-expand the arguments.Cyclosis
Over complicated and mostly not directly related the OP's question.Elinoreeliot
@Elinoreeliot Yes, it's complicated (but not over complicated). But especially for passwords it could be necessary, at least some of my passwords contain ampersands & and also quotes "Serendipity
@Cyclosis Some time ago, I developed another technique to retrieve even any multi-line arguments, it's safe against injection. See syntax-error-technicSerendipity
C
72

This technique has a bit of an overhead as you'll see, but it makes my batch files very easy to understand and quick to implement. As well as supporting the following structures:

>template.bat [-f] [--flag] [--namedvalue value] arg1 [arg2][arg3][...]

The jist of it is having the :init, :parse, and :main functions.

template.bat

@::!/dos/rocks
@echo off
goto :init

:header
    echo %__NAME% v%__VERSION%
    echo This is a sample batch file template,
    echo providing command-line arguments and flags.
    echo.
    goto :eof

:usage
    echo USAGE:
    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
    echo.
    echo.  /?, --help           shows this help
    echo.  /v, --version        shows the version
    echo.  /e, --verbose        shows detailed output
    echo.  -f, --flag value     specifies a named parameter value
    goto :eof

:version
    if "%~1"=="full" call :header & goto :eof
    echo %__VERSION%
    goto :eof

:missing_argument
    call :header
    call :usage
    echo.
    echo ****    MISSING "REQUIRED ARGUMENT"    ****
    echo.
    goto :eof

:init
    set "__NAME=%~n0"
    set "__VERSION=1.24"
    set "__YEAR=2023"

    set "__BAT_FILE=%~0"
    set "__BAT_PATH=%~dp0"
    set "__BAT_NAME=%~nx0"

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedOptionalArg="
    set "NamedFlag="

:parse
    if "%~1"=="" goto :validate

    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end

    if /i "%~1"=="/v"         call :version      & goto :end
    if /i "%~1"=="-v"         call :version      & goto :end
    if /i "%~1"=="--version"  call :version full & goto :end

    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse

    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse
    if /i "%~1"=="-f"         set "NamedFlag=%~2"   & shift & shift & goto :parse

    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse

    shift
    goto :parse

:validate
    if not defined UnNamedArgument call :missing_argument & goto :end

:main
    if defined OptVerbose (
        echo **** DEBUG IS ON
    )

    echo UnNamedArgument:    "%UnNamedArgument%"

    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided

    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
    if not defined NamedFlag           echo NamedFlag:          not provided

:end
    call :cleanup
    exit /B

:cleanup
    REM The cleanup function is only really necessary if you
    REM are _not_ using SETLOCAL.
    set "__NAME="
    set "__VERSION="
    set "__YEAR="

    set "__BAT_FILE="
    set "__BAT_PATH="
    set "__BAT_NAME="

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedArgument2="
    set "NamedFlag="

    goto :eof
Example usage returns
template.bat













template v1.24
This is a sample batch file template,
providing command-line arguments and flags.

USAGE:
template.bat [flags] "required argument" "optional argument"

/?, --help shows this help
/v, --version shows the version
/e, --verbose shows detailed output
-f, --flag value specifies a named parameter value

**** MISSING "REQUIRED ARGUMENT" ****
template.bat /?











template v1.24
This is a sample batch file template,
providing command-line arguments and flags.

USAGE:
template.bat [flags] "required argument" "optional argument"

/?, --help shows this help
/v, --version shows the version
/e, --verbose shows detailed output
-f, --flag value specifies a named parameter value
template.bat --v 1.24
template.bat --version


template v1.24
This is a sample batch file template,
providing command-line arguments and flags.
template.bat -e arg1



**** DEBUG IS ON
UnNamedArgument: "arg1"
UnNamedOptionalArg: not provided
NamedFlag: not provided
template.bat --flag "my flag" arg1 arg2
(without -e)

UnNamedArgument: "arg1"
UnNamedOptionalArg: "arg2"
NamedFlag: "my flag"
template.bat --verbose "argument #1" --flag "my flag" second


**** DEBUG IS ON
UnNamedArgument: "argument #1"
UnNamedOptionalArg: "second"
NamedFlag: "my flag"
Countermark answered 13/7, 2017 at 3:32 Comment(6)
What a piece of beauty! For future readers, I only want to highlight that the -f flag is not actually included in the parse-section yet. Just a heads up!Mascarenas
I accepted your edit @Flo. Thanks!Countermark
What does the first line, @::!/dos/rocks?, do?Barabbas
It is a commented line, so it does nothing. It's just for fun! Bash scripts have the shebang, so I started using that for my batch files. ;) (I know the shebang is actually instructions..)Countermark
This is amazing! Perfect after looking up an approach to have one singular file for bash and batch as mentioned from this SO post.Bermejo
you've covered everything. Great answer.Metonym
R
65

Yep, and just don't forget to use variables like %%1 when using if and for and the gang.

If you forget the double %, then you will be substituting in (possibly null) command line arguments and you will receive some pretty confusing error messages.

Rupee answered 25/8, 2008 at 18:16 Comment(5)
%% is only for if and for ?Meristic
It's worse than that - %% is used to prefix variables and command line parameters inside batch files. But when you use these commands from the command line, you use only % to prefix. Example: inside batch: for %%d in (*) do echo %%d from command line: for %d in (*) do echo %dSoelch
@SteveMidgley I upvoted your comment probably a year or so ago. I then promptly forgot about it and just today I was trying and staring confusingly at my for loop in the command line and wondering why it farted and did nothing else. So here's another virtual upvote from me. I'll be back in another year or so when I hit the same issue again.Foltz
We usually reserve the digits for command line processing and the double percent only applies to the for statement as far as I know. @for %%2 in (testing) do @echo %%2 %1 in a batch file, produces testing 1 when it is called with 1 (test 1).Elinoreeliot
The answer is wrong. %%1 doesn't access a command line argument, and it's also wrong for the IF command. Only the FOR command (in batch files) requires double percents, but even then %%1 would define a FOR parameter and doesn't access argumentsSerendipity
V
56

There is no need to complicate it. It is simply command %1 %2 parameters, for example,

@echo off

xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z

echo copied %1 to %2

pause

The "pause" displays what the batch file has done and waits for you to hit the ANY key. Save that as xx.bat in the Windows folder.

To use it, type, for example:

xx c:\f\30\*.* f:\sites\30

This batch file takes care of all the necessary parameters, like copying only files, that are newer, etc. I have used it since before Windows. If you like seeing the names of the files, as they are being copied, leave out the Q parameter.

Vespertine answered 18/4, 2012 at 23:46 Comment(0)
N
42

Everyone has answered with really complex responses, however it is actually really simple. %1 %2 %3 and so on are the arguements parsed to the file. %1 is arguement 1, %2 is arguement 2 and so on.

So, if I have a bat script containing this:

@echo off
echo %1

and when I run the batch script, I type in this:

C:> script.bat Hello

The script will simply output this:

Hello

This can be very useful for certain variables in a script, such as a name and age. So, if I have a script like this:

@echo off
echo Your name is: %1
echo Your age is: %2

When I type in this:

C:> script.bat Oliver 1000

I get the output of this:

Your name is: Oliver
Your age is: 1000
Nepean answered 6/6, 2021 at 14:37 Comment(2)
Great answer. Concise and easy to follow. 🔥Oria
how would you handle string variables that have spaces?Disclaim
B
38

In batch file

set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%

%1 and %2 return the first and second argument values respectively.

And in command line, pass the argument

Directory> batchFileName admin P@55w0rd 

Output will be

admin
P@55w0rd
Benefactor answered 18/10, 2019 at 9:24 Comment(0)
V
33
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Note: IF "%1"=="" will cause problems if %1 is enclosed in quotes itself.

In that case, use IF [%1]==[] or, in NT 4 (SP6) and later only, IF "%~1"=="" instead.

Vetiver answered 14/3, 2014 at 6:2 Comment(1)
True enough, but it barely touches the subject matter.Elinoreeliot
C
26

Let's keep this simple.

Here is the .cmd file.

@echo off
rem this file is named echo_3params.cmd
echo %1
echo %2
echo %3
set v1=%1
set v2=%2
set v3=%3
echo v1 equals %v1%
echo v2 equals %v2%
echo v3 equals %v3%

Here are 3 calls from the command line.

C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
1abc
2
def
v1 equals 1abc
v2 equals 2
v3 equals def

C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
1abc
"2 def"
"3 ghi"
v1 equals 1abc
v2 equals "2 def"
v3 equals "3 ghi"

C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
1abc
'2
def'
v1 equals 1abc
v2 equals '2
v3 equals def'

C:\Users\joeco>
Chandlery answered 31/12, 2015 at 17:59 Comment(2)
I know, a long time ago. But thank you! Simple is best, we can figure out the rest. Huh, a poem.Pharmacognosy
"Simple is best, we can figure out the rest"! Words to live by. Thanks, Alan.Chandlery
L
22
FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

This loops over the batch parameters (%*) either they are quoted or not, then echos each parameter.

Likelihood answered 25/11, 2014 at 4:39 Comment(1)
But fails with many different arguments, like test.bat *.txt, test.bat cat^&dog or Test.bat /?Serendipity
F
21

I wrote a simple read_params script that can be called as a function (or external .bat) and will put all variables into the current environment. It won't modify the original parameters because the function is being called with a copy of the original parameters.

For example, given the following command:

myscript.bat some -random=43 extra -greeting="hello world" fluff

myscript.bat would be able to use the variables after calling the function:

call :read_params %*

echo %random%
echo %greeting%

Here's the function:

:read_params
if not %1/==/ (
    if not "%__var%"=="" (
        if not "%__var:~0,1%"=="-" (
            endlocal
            goto read_params
        )
        endlocal & set %__var:~1%=%~1
    ) else (
        setlocal & set __var=%~1
    )
    shift
    goto read_params
)
exit /B

Limitations

  • Cannot load arguments with no value such as -force. You could use -force=true but I can't think of a way to allow blank values without knowing a list of parameters ahead of time that won't have a value.

Changelog

  • 2/18/2016
    • No longer requires delayed expansion
    • Now works with other command line arguments by looking for - before parameters.
Famished answered 17/2, 2016 at 0:24 Comment(3)
Been looking at using this method as I would like to pass arguments into a batch file in this manner. However I notice that after the variables are set, even after exiting the batch file the parameters are still set in the cmd if accessed and the batch has ended, they are not restored to their previous state. Should this method handle that situation?Tolman
On topic and better than some of the rest of the answers on this thread.Elinoreeliot
Extended it to support flag args (without values). Sorry for lack of formatting but it doesn't work in comments :read_params if not %1/==/ ( if not "%__var%"=="" ( if not "%__var:~0,1%"=="-" ( endlocal goto read_params ) endlocal & set %__var:~1%=%~1 ) else ( setlocal & set __var=%~1 ) shift goto read_params ) else ( if not "%__var%"=="" ( endlocal & set %__var:~1%=1 ) )Cespitose
H
13

Inspired by an answer elsewhere by @Jon, I have crafted a more general algorithm for extracting named parameters, optional values, and switches.

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]

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
  • Use SETLOCAL so that the variables don't escape into the calling environment.
  • Don't forget to initialize the variables SET FOO=, etc. in case someone defined them in the calling environment.
  • Use %~1 to remove quotes.
  • Use IF "%ARG%" == "" and not IF [%ARG%] == [] because [ and ] don't play will at all with values ending in a space.
  • Even if you SHIFT inside an IF block, the current args such as %~1 don't get updated because they are determined when the IF is parsed. You could use %~1 and %~2 inside the IF block, but it would be confusing because you had a SHIFT. You could put the SHIFT at the end of the block for clarity, but that might get lost and/or confuse people as well. So "capturing" %~1 and %~1 outside the block seems best.
  • You don't want to use a parameter in place of another parameter's optional value, so you have to check IF NOT "%ARG:~0,2%" == "--".
  • Be careful only to SHIFT when you use one of the parameters.
  • The duplicate code SET FOO=%DEFAULT_FOO% is regrettable, but the alternative would be to add an IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% outside the IF NOT "%ARG%" == "" block. However because this is still inside the IF "%PARAM%" == "--foo" block, the %FOO% value would have been evaluated and set before you ever entered the block, so you would never detect that both the --foo parameter was present and also that the %FOO% value was missing.
  • Note that ECHO Missing bar value. 1>&2 sends the error message to stderr.
  • Want a blank line in a Windows batch file? You gotta use ECHO: or one of the variations.
Henleigh answered 2/6, 2018 at 2:41 Comment(0)
S
10

To refer to a set variable in command line you would need to use %a% so for example:

set a=100 
echo %a%  
rem output = 100 

Note: This works for Windows 7 pro.

Subteen answered 14/11, 2013 at 18:16 Comment(0)
Y
7

enter image description here

For to use looping get all arguments and in pure batch:

Obs: For using without: ?*&|<>


@echo off && setlocal EnableDelayedExpansion

 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
     call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt!
     )do echo/ The argument n:%%l is: !_arg_[%%l]!
 )

endlocal 

Your code is ready to do something with the argument number where it needs, like...

 @echo off && setlocal EnableDelayedExpansion

 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
 
 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
 
Yuu answered 11/2, 2019 at 16:44 Comment(0)
S
4

Simple solution(even though question is old)

Test1.bat

echo off
echo "Batch started"
set arg1=%1
echo "arg1 is %arg1%"
echo on
pause

CallTest1.bat

call "C:\Temp\Test1.bat" pass123

output

YourLocalPath>call "C:\Temp\test.bat" pass123

YourLocalPath>echo off
"Batch started"
"arg1 is pass123"

YourLocalPath>pause
Press any key to continue . . .

Where YourLocalPath is current directory path.

To keep things simple store the command param in variable and use variable for comparison.

Its not just simple to write but its simple to maintain as well so if later some other person or you read your script after long period of time, it will be easy to understand and maintain.

To write code inline : see other answers.

Sought answered 3/7, 2018 at 13:48 Comment(0)
G
3

Make a new batch file (example: openclass.bat) and write this line in the file:

java %~n1

Then place the batch file in, let's say, the system32 folder, go to your Java class file, right click, Properties, Open with..., then find your batch file, select it and that's that...

It works for me.

PS: I can't find a way to close the cmd window when I close the Java class. For now...

Giron answered 6/2, 2011 at 13:33 Comment(2)
You can close the cmd window after the process has closed using the following command in a batch script: start /wait java %~n1Termination
Advising the public to put random script files in the system32 directory is irresponsible. This answer really doesn't scratch the surface of the topic of this thread.Elinoreeliot
P
2

Paired arguments

If you prefer passing the arguments in a key-value pair you can use something like this:

@echo off

setlocal enableDelayedExpansion

:::::  asigning arguments as a key-value pairs:::::::::::::
set counter=0
for %%# in (%*) do (    
    set /a counter=counter+1
    set /a even=counter%%2
    
    if !even! == 0 (
        echo setting !prev! to %%#
        set "!prev!=%%~#"
    )
    set "prev=%%~#"
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: showing the assignments
echo %one% %two% %three% %four% %five%

endlocal

And an example :

c:>argumentsDemo.bat one 1 "two" 2 three 3 four 4 "five" 5
1 2 3 4 5

Predefined variables

You can also set some environment variables in advance. It can be done by setting them in the console or setting them from my computer:

@echo off

if defined variable1 (
    echo %variable1%
)

if defined variable2 (
    echo %variable2%
)

and calling it like:

c:\>set variable1=1

c:\>set variable2=2

c:\>argumentsTest.bat
1
2

File with listed values

You can also point to a file where the needed values are preset. If this is the script:

@echo off

setlocal
::::::::::
set "VALUES_FILE=E:\scripts\values.txt"
:::::::::::


for /f "usebackq eol=: tokens=* delims=" %%# in ("%VALUES_FILE%") do set "%%#"

echo %key1% %key2% %some_other_key%

endlocal

and values file is this:

:::: use EOL=: in the FOR loop to use it as a comment

key1=value1

key2=value2

:::: do not left spaces arround the =
:::: or at the begining of the line

some_other_key=something else

and_one_more=more

the output of calling it will be:

value1 value2 something else

Of course you can combine all approaches. Check also arguments syntax , shift

Phalansterian answered 9/11, 2020 at 10:20 Comment(0)
E
0

If you're worried about security/password theft (that led you to design this solution that takes login credentials at execution instead of static hard coding without the need for a database), then you could store the api or half the code of password decryption or decryption key in the program file, so at run time, user would type username/password in console to be hashed/decrypted before passed to program code for execution via set /p, if you're looking at user entering credentials at run time.

If you're running a script to run your program with various user/password, then command line args will suit you.

If you're making a test file to see the output/effects of different logins, then you could store all the logins in an encrypted file, to be passed as arg to test.cmd, unless you wanna sit at command line & type all the logins until finished.

The number of args that can be supplied is limited to total characters on command line. To overcome this limitation, the previous paragraph trick is a workaround without risking exposure of user passwords.

Eisele answered 10/9, 2021 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.