Help on an internal command of cmd.exe can be get and read by opening a command prompt window and running help command or command /?. Try this out with help call or call /? and help for or for /? and help shift or shift /?.
Standard console applications like ping.exe or xcopy.exe in folder %SystemRoot%\System32 support also being executed with option /? to show help. Try it out with ping /?, choice /? or find /?. Those executables are also known as external commands as available by default on Windows (depending on Windows version), but not being internal commands of cmd.exe.
Here is code of caller.bat with some really ugly strings to pass:
@echo off
setlocal
set "vara="""
set "varb=B"
set "varc="C""
set "vard=Hello!"
set "vare="%%PATH%%""
set "varf=F"
set "varg=G"
set "varh=Operators: &()[]{}^=;!'+,`~<>|"
set "vari=I"
set "varj=J"
set "vark=K"
set "varl=!PATHEXT!"
set "varm=M"
set "varn=N"
cls
echo Variables set in %~nx0:
echo/
set var
echo/
echo Calling passTo.bat
echo/
setlocal EnableDelayedExpansion
call passTo.bat %vara% %varb% %varc% !vard! !vare! %varf% %varg% "!varh!" %vari% %varj% %vark% "!varl!" %varm% %varn%
endlocal
endlocal
The output of this batch file is:
Variables set in caller.bat:
vara=""
varb=B
varc="C"
vard=Hello!
vare="%PATH%"
varf=F
varg=G
varh=Operators: &()[]{}^=;!'+,`~<>|
vari=I
varj=J
vark=K
varl=!PATHEXT!
varm=M
varn=N
Calling passTo.bat
And here is code of passTo.bat with three methods to process passed arguments.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Is this batch file called with at least 1 argument string?
if not "%~1" == "" goto MainCode
rem It can be even an empty argument string, i.e. just "".
if #%1 == #"" goto Maincode
echo %~nx0 is called with no argument.
goto EndBatch
rem ArgumentToVariable is a subroutine called from FOR loop below.
:ArgumentToVariable
call set "Letter=%%Indices:~%Index%,1%%
set var%Letter%=%1
set /A Index+=1
goto :EOF
:MainCode
echo Inside %~nx0 executed with the arguments:
echo %*
set "Index=0"
set "Indices=abcdefghijklmn"
for %%I in (%*) do call :ArgumentToVariable %%I
echo/
echo Arguments list processed with command FOR with using a subroutine:
echo/
set var
rem End current local environment to discard all environment variables.
endlocal
rem Setup a new local environment to recreate all variables once again.
setlocal EnableExtensions EnableDelayedExpansion
set "Index=0"
set "Indices=abcdefghijklmn"
for %%I in (%*) do (
set "Letter=Indices:~!Index!,1"
call set "Letter=%%!Letter!%%"
set var!Letter!=%%I
set /A Index+=1
)
echo/
echo Arguments list processed with command FOR with using delayed expansion:
echo/
set var
rem End current local environment to discard all environment variables.
endlocal
rem Setup a new local environment to recreate all variables once again.
setlocal EnableExtensions DisableDelayedExpansion
set "Index=0"
set "Indices=abcdefghijklmn"
:ShiftLoop
call set "Letter=%%Indices:~%Index%,1%%
set var%Letter%=%1
set /A Index+=1
shift
if not "%~1" == "" goto ShiftLoop
if #%1 == #"" goto ShiftLoop
echo/
echo Arguments list processed with command SHIFT:
echo/
set var
:EndBatch
endlocal
echo/
echo Variables list as defined by parent batch file:
echo/
set var
And the output of passTo.bat is:
Inside passTo.bat executed with the arguments:
"" B "C" Hello! "C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem" F G "
Operators: &()[]{}^^=;!'+,`~<>|" I J K "!PATHEXT!" M N
Arguments list processed with command FOR with using a subroutine:
vara=""
varb=B
varc="C"
vard=Hello!
vare="C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem"
varf=F
varg=G
varh="Operators: &()[]{}^^^^=;!'+,`~<>|"
vari=I
varj=J
vark=K
varl="!PATHEXT!"
varm=M
varn=N
Arguments list processed with command FOR with using delayed expansion:
vara=""
varb=B
varc="C"
vard=Hello\Windows\System32
vare=C:\Windows
varf=C:\Windows\system32\wbem" F G "Operators:
varg=&()[]{}
varh=PATHEXT" M N
vari=I
varj=J
vark=K
varl=!PATHEXT!
varm=M
varn=N
Arguments list processed with command SHIFT:
vara=""
varb=B
varc="C"
vard=Hello!
vare="C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem"
varf=F
varg=G
varh="Operators: &()[]{}^^=;!'+,`~<>|"
vari=I
varj=J
vark=K
varl="!PATHEXT!"
varm=M
varn=N
Variables list as defined by parent batch file:
vara=""
varb=B
varc="C"
vard=Hello!
vare="%PATH%"
varf=F
varg=G
varh=Operators: &()[]{}^=;!'+,`~<>|
vari=I
varj=J
vark=K
varl=!PATHEXT!
varm=M
varn=N
It can be seen on comparing the lists that some argument strings are not passed unmodified from batch file caller.bat to passTo.bat via arguments list.
The best result is produced by the method using command SHIFT on passing strings via arguments to another batch file. But the really best solution is passing strings from one batch file to another one using environment variables as shown by last variables list being identical to output of caller.bat because of passTo.bat outputs the environment variables defined by parent batch file.
All three methods work well on parsing simple strings like file name strings enclosed in double quotes and not containing % or ! or ^ via arguments list.
And using a variable naming scheme like var_1, var_2, ... or var[1], var[2], ... would make arguments and variables processing definitely easier because integer numbers can be easily incremented while getting next letter from a list is more difficult to achieve.
See also Copy text from a Windows CMD window to clipboard.