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.