[windows] Get list of passed arguments in Windows batch script (.bat)

I'd like to find a Windows batch counterpart to Bash's $@ that holds a list of all arguments passed into a script.

Or I have to bother with shift?

This question is related to windows batch-file

The answer is


Sometimes I need to extract several command line parameters, but not all of them and not from the first one. Let's assume the following call:

Test.bat uno dos tres cuatro cinco seis siete

Of course, the extension ".bat" is not needed at least you have test.exe in same folder. What we want is to get the output "tres cuatro cinco" (no matter if one line or three). The goal is that only I need three parameters and starting in the third one. In order to have a simple example the action for each one is just "echo", but you can think in some other more complex action over the selected parameters.

I've produced some examples, (options) in order you can see which one you consider better for you. Unfortunately, there is not a nice (or I don't know about) way based on a for loop over the range like "for %%i in (%3, 1, %5)".

@echo off 
setlocal EnableDelayedExpansion

echo Option 1: one by one (same line)
echo %3, %4, %5
echo.

echo Option 2: Loop For one by one
for %%a in (%3, %4, %5) do echo %%a
echo.

echo Option 3: Loop For with check of limits
set i=0
for %%a in (%*) do (
    set /A i=i+1
    If !i! GTR 2 if !i! LSS 6 echo %%a
)
echo.

echo Option 4: Loop For with auxiliary list
for /l %%i in (3,1,5) do  (
    set a=%%i
    set b=echo %%
    set b=!b!!a!
    call !b!
)
echo.

echo Option 5: Assigning to an array of elements previously
set e[0]=%0
set i=0 
for %%a in (%*) do (
    set /A i=i+1
    set e[!i!]=%%a
)
for  /l %%i in (3,1,5) do (
    echo !e[%%i]!
)
echo.

echo Option 6: using shift and goto loop. It doesn't work with for loop
set i=2
:loop6
    set /A i=i+1
    echo %3
    shift
    If %i% LSS 5 goto :loop6

Probably you can find more options or combine several ones. Enjoy them.


Here is a fairly simple way to get the args and set them as env vars. In this example I will just refer to them as Keys and Values.

Save the following code example as "args.bat". Then call the batch file you saved from a command line. example: arg.bat --x 90 --y 120

I have provided some echo commands to step you through the process. But the end result is that --x will have a value of 90 and --y will have a value of 120(that is if you run the example as specified above ;-) ).

You can then use the 'if defined' conditional statement to determine whether or not to run your code block. So lets say run: "arg.bat --x hello-world" I could then use the statement "IF DEFINED --x echo %--x%" and the results would be "hello-world". It should make more sense if you run the batch.

@setlocal enableextensions enabledelayedexpansion
@ECHO off
ECHO.
ECHO :::::::::::::::::::::::::: arg.bat example :::::::::::::::::::::::::::::::
ECHO :: By:      User2631477, 2013-07-29                                   ::
ECHO :: Version: 1.0                                                         ::
ECHO :: Purpose: Checks the args passed to the batch.                        ::
ECHO ::                                                                      ::
ECHO :: Start by gathering all the args with the %%* in a for loop.          ::
ECHO ::                                                                      ::
ECHO :: Now we use a 'for' loop to search for our keys which are identified  ::
ECHO :: by the text '--'. The function then sets the --arg ^= to the next    ::
ECHO :: arg. "CALL:Function_GetValue" ^<search for --^> ^<each arg^>         ::
ECHO ::                                                                      ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ECHO.

ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: From the command line you could pass... arg.bat --x 90 --y 220       ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
ECHO.Checking Args:"%*"

FOR %%a IN (%*) do (
    CALL:Function_GetValue "--","%%a" 
)

ECHO.
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: Now lets check which args were set to variables...                   ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: For this we are using the CALL:Function_Show_Defined "--x,--y,--z"   ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
CALL:Function_Show_Defined "--x,--y,--z"
endlocal
goto done

:Function_GetValue

REM First we use find string to locate and search for the text.
echo.%~2 | findstr /C:"%~1" 1>nul

REM Next we check the errorlevel return to see if it contains a key or a value
REM and set the appropriate action.

if not errorlevel 1 (
  SET KEY=%~2
) ELSE (
  SET VALUE=%~2
)
IF DEFINED VALUE (
    SET %KEY%=%~2
    ECHO.
    ECHO ::::::::::::::::::::::::: %~0 ::::::::::::::::::::::::::::::
    ECHO :: The KEY:'%KEY%' is now set to the VALUE:'%VALUE%'                     ::
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO.
    ECHO %KEY%=%~2
    ECHO.
    REM It's important to clear the definitions for the key and value in order to
    REM search for the next key value set.
    SET KEY=
    SET VALUE=
)
GOTO:EOF

:Function_Show_Defined 
ECHO.
ECHO ::::::::::::::::::: %~0 ::::::::::::::::::::::::::::::::
ECHO :: Checks which args were defined i.e. %~2
ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
SET ARGS=%~1
for %%s in (%ARGS%) DO (
    ECHO.
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO :: For the ARG: '%%s'                         
    IF DEFINED %%s (
        ECHO :: Defined as: '%%s=!%%s!'                                             
    ) else (
        ECHO :: Not Defined '%%s' and thus has no value.
    )
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO.
)
goto:EOF

:done

%1 ... %n and %* holds the arguments, but it can be tricky to access them, because the content will be interpreted.
Therefore it is impossible to handle something like this with normal statements

myBatch.bat "&"^&

Each line fails, as cmd.exe try to execute one of the ampersands (the content of %1 is "&"&)

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

But there exists a workaround with a temporary file

@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 .. %*).
But to be able to redirect the output of 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.

The FOR /F should be work with delayed expansion off, else contents with "!" would be destroyed.
After removing the extra characters in param1 and you got it.

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

Edit: One remark to %0

%0 contains the command used to call the batch, also preserving the case like in FoO.BaT
But after a call to a function %0 and also in %~0 contains the function name (or better the string that was used to call the function).
But with %~f0 you still can recall the filename.

@echo off
echo main %0, %~0, %~f0
call :myLabel+xyz
exit /b

:MYlabel
echo func %0, %~0, %~f0
exit /b

Output

main test.bat, test.bat, C:\temp\test.bat
func :myLabel+xyz, :myLabel+xyz, C:\temp\test.bat

%* seems to hold all of the arguments passed to the script.


The way to retrieve all the args to a script is here:

@ECHO off
ECHO The %~nx0 script args are...
for %%I IN (%*) DO ECHO %%I
pause

Lot of the information above led me to further research and ultimately my answer so I wanted to contribute what I wound up doing in hopes it helps someone else:

  • I also wanted to pass a varied number of variables to a batch file so that they could be processed within the file.

  • I was ok with passing them to the batch file using quotes

  • I would want them processed similar to the below - but using a loop instead of writing out manually:

So I wanted to execute this:

prog_ZipDeleteFiles.bat "_appPath=C:\Services\Logs\PCAP" "_appFile=PCAP*.?"

And via the magic of for loops do this within the batch file:

set "_appPath=C:\Services\Logs\PCAP"
set "_appFile=PCAP*.?"

Problem I was having is that all my attempts to use a for loop weren't working. The below example:

for /f "tokens* delims= " in %%A (%*) DO (
   set %%A
)

would just do:

set "_appPath=C:\Services\Logs\PCAP"

and not:

set "_appPath=C:\Services\Logs\PCAP"
set "_appFile=PCAP*.?"

even after setting

SETLOCAL EnableDelayedExpansion

Reason was that the for loop read the whole line and assigned my second parameter to %%B during the first iteration of the loop. Because %* represents all arguments, there is only a single line to process - ergo only one pass of the for loop happens. This is by design it turns out, and my logic was wrong.

So I stopped trying to use a for loop and simplified what I was trying to do by using if, shift, and a goto statement. Agreed its a bit of a hack but it's more suited to my needs. I can loop through all of the arguments and then use an if statement to drop out of the loop once I process them all.

The winning statement for what I was trying to accomplish:

echo on
:processArguments
:: Process all arguments in the order received
if defined %1 then (
    set %1
    shift
    goto:processArguments
) ELSE (
    echo off 
)

UPDATE - I had to modify to the below instead, I was exposing all of the environment variables when trying to reference %1 and using shift in this manner:

echo on
shift
:processArguments
:: Process all arguments in the order received
if defined %0 then (
    set %0
    shift
    goto:processArguments
) ELSE (
    echo off 
)

The following code simulates an array ('params') - takes the parameters received by the script and stores them in the variables params_1 .. params_n, where n=params_0=the number of elements of the array:

@echo off

rem Storing the program parameters into the array 'params':
rem Delayed expansion is left disabled in order not to interpret "!" in program parameters' values;
rem however, if a parameter is not quoted, special characters in it (like "^", "&", "|") get interpreted at program launch
set /a count=0
:repeat
    set /a count+=1
    set "params_%count%=%~1"
    shift
    if defined params_%count% (
        goto :repeat
    ) else (
        set /a count-=1
    )    
set /a params_0=count

rem Printing the program parameters stored in the array 'params':
rem After the variables params_1 .. params_n are set with the program parameters' values, delayed expansion can
rem be enabled and "!" are not interpreted in the variables params_1 .. params_n values
setlocal enabledelayedexpansion
    for /l %%i in (1,1,!params_0!) do (
        echo params_%%i: "!params_%%i!"
    )
endlocal

pause
goto :eof

If you have parameters in quotes that containing spaces, %* will not work correctly. The best solution I found is to have a loop that joins all arguments: https://serverfault.com/a/22541

set args=%1
shift
:start
if [%1] == [] goto done
set args=%args% %1
shift
goto start

:done
(use %args% here)

@echo off
:start

:: Insert your code here
echo.%%1 is now:%~1
:: End insert your code here

if "%~2" NEQ "" (
    shift
    goto :start
)

%* seems to hold all of the arguments passed to the script.


The following code simulates an array ('params') - takes the parameters received by the script and stores them in the variables params_1 .. params_n, where n=params_0=the number of elements of the array:

@echo off

rem Storing the program parameters into the array 'params':
rem Delayed expansion is left disabled in order not to interpret "!" in program parameters' values;
rem however, if a parameter is not quoted, special characters in it (like "^", "&", "|") get interpreted at program launch
set /a count=0
:repeat
    set /a count+=1
    set "params_%count%=%~1"
    shift
    if defined params_%count% (
        goto :repeat
    ) else (
        set /a count-=1
    )    
set /a params_0=count

rem Printing the program parameters stored in the array 'params':
rem After the variables params_1 .. params_n are set with the program parameters' values, delayed expansion can
rem be enabled and "!" are not interpreted in the variables params_1 .. params_n values
setlocal enabledelayedexpansion
    for /l %%i in (1,1,!params_0!) do (
        echo params_%%i: "!params_%%i!"
    )
endlocal

pause
goto :eof

%* seems to hold all of the arguments passed to the script.


You can use For Commad,to get list of Arg.

Help : For /? Help : Setlocal /?

Here is my way =

@echo off
::For Run Use This = cmd /c ""Args.cmd" Hello USER Scientist etc"
setlocal EnableDelayedExpansion
set /a Count=0
for %%I IN (%*) DO (
 Echo Arg_!Count! = %%I
 set /a Count+=1 
)
Echo Count Of Args = !Count!
Endlocal

Do not need Shift command.


enter image description here

For to use looping to 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_!")

:: write/test these arguments/parameters ::
for /l %%l in (1 1 !_cnt!)do echo/ The argument n:%%l is: !_arg_[%%l]!

goto :eof 

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_!"

echo= !_arg_[1]! !_arg_[2]! !_arg_[2]!> log.txt

I found that next time when you need to look up these information. Instead of opening a browser and google it, you could just type call /? in your cmd and you'll get it:

...

%* in a batch script refers to all the arguments (e.g. %1 %2 %3
    %4 %5 ...)

Substitution of batch parameters (%n) has been enhanced.  You can
now use the following optional syntax:

    %~1         - expands %1 removing any surrounding quotes (")
    %~f1        - expands %1 to a fully qualified path name
    %~d1        - expands %1 to a drive letter only
    %~p1        - expands %1 to a path only
    %~n1        - expands %1 to a file name only
    %~x1        - expands %1 to a file extension only
    %~s1        - expanded path contains short names only
    %~a1        - expands %1 to file attributes
    %~t1        - expands %1 to date/time of file
    %~z1        - expands %1 to size of file
    %~$PATH:1   - searches the directories listed in the PATH
                   environment variable and expands %1 to the fully
                   qualified name of the first one found.  If the
                   environment variable name is not defined or the
                   file is not found by the search, then this
                   modifier expands to the empty string

The modifiers can be combined to get compound results:

    %~dp1       - expands %1 to a drive letter and path only
    %~nx1       - expands %1 to a file name and extension only
    %~dp$PATH:1 - searches the directories listed in the PATH
                   environment variable for %1 and expands to the
                   drive letter and path of the first one found.
    %~ftza1     - expands %1 to a DIR like output line

In the above examples %1 and PATH can be replaced by other
valid values.  The %~ syntax is terminated by a valid argument
number.  The %~ modifiers may not be used with %*

If you have parameters in quotes that containing spaces, %* will not work correctly. The best solution I found is to have a loop that joins all arguments: https://serverfault.com/a/22541

set args=%1
shift
:start
if [%1] == [] goto done
set args=%args% %1
shift
goto start

:done
(use %args% here)

enter image description here

For to use looping to 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_!")

:: write/test these arguments/parameters ::
for /l %%l in (1 1 !_cnt!)do echo/ The argument n:%%l is: !_arg_[%%l]!

goto :eof 

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_!"

echo= !_arg_[1]! !_arg_[2]! !_arg_[2]!> log.txt

The way to retrieve all the args to a script is here:

@ECHO off
ECHO The %~nx0 script args are...
for %%I IN (%*) DO ECHO %%I
pause

@echo off
:start

:: Insert your code here
echo.%%1 is now:%~1
:: End insert your code here

if "%~2" NEQ "" (
    shift
    goto :start
)

Sometimes I need to extract several command line parameters, but not all of them and not from the first one. Let's assume the following call:

Test.bat uno dos tres cuatro cinco seis siete

Of course, the extension ".bat" is not needed at least you have test.exe in same folder. What we want is to get the output "tres cuatro cinco" (no matter if one line or three). The goal is that only I need three parameters and starting in the third one. In order to have a simple example the action for each one is just "echo", but you can think in some other more complex action over the selected parameters.

I've produced some examples, (options) in order you can see which one you consider better for you. Unfortunately, there is not a nice (or I don't know about) way based on a for loop over the range like "for %%i in (%3, 1, %5)".

@echo off 
setlocal EnableDelayedExpansion

echo Option 1: one by one (same line)
echo %3, %4, %5
echo.

echo Option 2: Loop For one by one
for %%a in (%3, %4, %5) do echo %%a
echo.

echo Option 3: Loop For with check of limits
set i=0
for %%a in (%*) do (
    set /A i=i+1
    If !i! GTR 2 if !i! LSS 6 echo %%a
)
echo.

echo Option 4: Loop For with auxiliary list
for /l %%i in (3,1,5) do  (
    set a=%%i
    set b=echo %%
    set b=!b!!a!
    call !b!
)
echo.

echo Option 5: Assigning to an array of elements previously
set e[0]=%0
set i=0 
for %%a in (%*) do (
    set /A i=i+1
    set e[!i!]=%%a
)
for  /l %%i in (3,1,5) do (
    echo !e[%%i]!
)
echo.

echo Option 6: using shift and goto loop. It doesn't work with for loop
set i=2
:loop6
    set /A i=i+1
    echo %3
    shift
    If %i% LSS 5 goto :loop6

Probably you can find more options or combine several ones. Enjoy them.


You can use For Commad,to get list of Arg.

Help : For /? Help : Setlocal /?

Here is my way =

@echo off
::For Run Use This = cmd /c ""Args.cmd" Hello USER Scientist etc"
setlocal EnableDelayedExpansion
set /a Count=0
for %%I IN (%*) DO (
 Echo Arg_!Count! = %%I
 set /a Count+=1 
)
Echo Count Of Args = !Count!
Endlocal

Do not need Shift command.


I found that next time when you need to look up these information. Instead of opening a browser and google it, you could just type call /? in your cmd and you'll get it:

...

%* in a batch script refers to all the arguments (e.g. %1 %2 %3
    %4 %5 ...)

Substitution of batch parameters (%n) has been enhanced.  You can
now use the following optional syntax:

    %~1         - expands %1 removing any surrounding quotes (")
    %~f1        - expands %1 to a fully qualified path name
    %~d1        - expands %1 to a drive letter only
    %~p1        - expands %1 to a path only
    %~n1        - expands %1 to a file name only
    %~x1        - expands %1 to a file extension only
    %~s1        - expanded path contains short names only
    %~a1        - expands %1 to file attributes
    %~t1        - expands %1 to date/time of file
    %~z1        - expands %1 to size of file
    %~$PATH:1   - searches the directories listed in the PATH
                   environment variable and expands %1 to the fully
                   qualified name of the first one found.  If the
                   environment variable name is not defined or the
                   file is not found by the search, then this
                   modifier expands to the empty string

The modifiers can be combined to get compound results:

    %~dp1       - expands %1 to a drive letter and path only
    %~nx1       - expands %1 to a file name and extension only
    %~dp$PATH:1 - searches the directories listed in the PATH
                   environment variable for %1 and expands to the
                   drive letter and path of the first one found.
    %~ftza1     - expands %1 to a DIR like output line

In the above examples %1 and PATH can be replaced by other
valid values.  The %~ syntax is terminated by a valid argument
number.  The %~ modifiers may not be used with %*

Windows version (needs socat though)

C:\Program Files (x86)\Git\bin>type gitproxy.cmd
socat STDIO PROXY:proxy.mycompany.de:%1:%2,proxyport=3128

setting it up:

C:\Users\exhau\AppData\Roaming\npm>git config --global core.gitproxy gitproxy.cmd

Here is a fairly simple way to get the args and set them as env vars. In this example I will just refer to them as Keys and Values.

Save the following code example as "args.bat". Then call the batch file you saved from a command line. example: arg.bat --x 90 --y 120

I have provided some echo commands to step you through the process. But the end result is that --x will have a value of 90 and --y will have a value of 120(that is if you run the example as specified above ;-) ).

You can then use the 'if defined' conditional statement to determine whether or not to run your code block. So lets say run: "arg.bat --x hello-world" I could then use the statement "IF DEFINED --x echo %--x%" and the results would be "hello-world". It should make more sense if you run the batch.

@setlocal enableextensions enabledelayedexpansion
@ECHO off
ECHO.
ECHO :::::::::::::::::::::::::: arg.bat example :::::::::::::::::::::::::::::::
ECHO :: By:      User2631477, 2013-07-29                                   ::
ECHO :: Version: 1.0                                                         ::
ECHO :: Purpose: Checks the args passed to the batch.                        ::
ECHO ::                                                                      ::
ECHO :: Start by gathering all the args with the %%* in a for loop.          ::
ECHO ::                                                                      ::
ECHO :: Now we use a 'for' loop to search for our keys which are identified  ::
ECHO :: by the text '--'. The function then sets the --arg ^= to the next    ::
ECHO :: arg. "CALL:Function_GetValue" ^<search for --^> ^<each arg^>         ::
ECHO ::                                                                      ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ECHO.

ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: From the command line you could pass... arg.bat --x 90 --y 220       ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
ECHO.Checking Args:"%*"

FOR %%a IN (%*) do (
    CALL:Function_GetValue "--","%%a" 
)

ECHO.
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: Now lets check which args were set to variables...                   ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO :: For this we are using the CALL:Function_Show_Defined "--x,--y,--z"   ::
ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
CALL:Function_Show_Defined "--x,--y,--z"
endlocal
goto done

:Function_GetValue

REM First we use find string to locate and search for the text.
echo.%~2 | findstr /C:"%~1" 1>nul

REM Next we check the errorlevel return to see if it contains a key or a value
REM and set the appropriate action.

if not errorlevel 1 (
  SET KEY=%~2
) ELSE (
  SET VALUE=%~2
)
IF DEFINED VALUE (
    SET %KEY%=%~2
    ECHO.
    ECHO ::::::::::::::::::::::::: %~0 ::::::::::::::::::::::::::::::
    ECHO :: The KEY:'%KEY%' is now set to the VALUE:'%VALUE%'                     ::
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO.
    ECHO %KEY%=%~2
    ECHO.
    REM It's important to clear the definitions for the key and value in order to
    REM search for the next key value set.
    SET KEY=
    SET VALUE=
)
GOTO:EOF

:Function_Show_Defined 
ECHO.
ECHO ::::::::::::::::::: %~0 ::::::::::::::::::::::::::::::::
ECHO :: Checks which args were defined i.e. %~2
ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ECHO.
SET ARGS=%~1
for %%s in (%ARGS%) DO (
    ECHO.
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO :: For the ARG: '%%s'                         
    IF DEFINED %%s (
        ECHO :: Defined as: '%%s=!%%s!'                                             
    ) else (
        ECHO :: Not Defined '%%s' and thus has no value.
    )
    ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ECHO.
)
goto:EOF

:done

Windows version (needs socat though)

C:\Program Files (x86)\Git\bin>type gitproxy.cmd
socat STDIO PROXY:proxy.mycompany.de:%1:%2,proxyport=3128

setting it up:

C:\Users\exhau\AppData\Roaming\npm>git config --global core.gitproxy gitproxy.cmd

Lot of the information above led me to further research and ultimately my answer so I wanted to contribute what I wound up doing in hopes it helps someone else:

  • I also wanted to pass a varied number of variables to a batch file so that they could be processed within the file.

  • I was ok with passing them to the batch file using quotes

  • I would want them processed similar to the below - but using a loop instead of writing out manually:

So I wanted to execute this:

prog_ZipDeleteFiles.bat "_appPath=C:\Services\Logs\PCAP" "_appFile=PCAP*.?"

And via the magic of for loops do this within the batch file:

set "_appPath=C:\Services\Logs\PCAP"
set "_appFile=PCAP*.?"

Problem I was having is that all my attempts to use a for loop weren't working. The below example:

for /f "tokens* delims= " in %%A (%*) DO (
   set %%A
)

would just do:

set "_appPath=C:\Services\Logs\PCAP"

and not:

set "_appPath=C:\Services\Logs\PCAP"
set "_appFile=PCAP*.?"

even after setting

SETLOCAL EnableDelayedExpansion

Reason was that the for loop read the whole line and assigned my second parameter to %%B during the first iteration of the loop. Because %* represents all arguments, there is only a single line to process - ergo only one pass of the for loop happens. This is by design it turns out, and my logic was wrong.

So I stopped trying to use a for loop and simplified what I was trying to do by using if, shift, and a goto statement. Agreed its a bit of a hack but it's more suited to my needs. I can loop through all of the arguments and then use an if statement to drop out of the loop once I process them all.

The winning statement for what I was trying to accomplish:

echo on
:processArguments
:: Process all arguments in the order received
if defined %1 then (
    set %1
    shift
    goto:processArguments
) ELSE (
    echo off 
)

UPDATE - I had to modify to the below instead, I was exposing all of the environment variables when trying to reference %1 and using shift in this manner:

echo on
shift
:processArguments
:: Process all arguments in the order received
if defined %0 then (
    set %0
    shift
    goto:processArguments
) ELSE (
    echo off 
)

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to batch-file

'ls' is not recognized as an internal or external command, operable program or batch file '' is not recognized as an internal or external command, operable program or batch file XCOPY: Overwrite all without prompt in BATCH CanĀ“t run .bat file under windows 10 Execute a batch file on a remote PC using a batch file on local PC Windows batch - concatenate multiple text files into one How do I create a shortcut via command-line in Windows? Getting Error:JRE_HOME variable is not defined correctly when trying to run startup.bat of Apache-Tomcat Curl not recognized as an internal or external command, operable program or batch file Best way to script remote SSH commands in Batch (Windows)