Quoting the answer in full because it so tremendously useful [WayBack] batch file – SHIFT doesn’t affect %* – Stack Overflow.
Especially the quoting/dequoting bits and the clever trick reconstructing %* into a batch file variable (minus double spaces).
Thanks so much James-K!
As you know,
shift
has no effect on%*
, but you can construct a%*
equivalent.We’ll call the following
line.bat
:@echo off set line=%1 :loop shift if not "%1"=="" ( set line=%line% %1 goto :loop ) echo %%* = %* echo line = %line%
If you type in the following command (Notice the double space between 3 and 4) :
line 1 2 3 4 bla dee dah
You will get the following output :
%* = 1 2 3 4 bla dee dah line = 1 2 3 4 bla dee dah
Note that
%*
retains multiple spaces, while using the%n
notation does not.
Using something like this, you can allow your users to put their parameters in any order.
:loop :: Single variable parameters if "%1"=="something" set something=true :: Multi variable parameters if "%~1"=="/source" shift & set source=%1 shift if not "%~1"=="" goto :loop
Notice that in the Multi-variable parameter statement I include one
shift
statement and oneset
statement separated by an ampersand (&). The&
tells the command processor that a separate command to be executed follows.
EDIT:
FYI: I recommend double quotes when checking the contents of variables. Usually you can use anycharacter, and you don’t even need to use two because they are just there to insure that an empty variable does not cause an error. For instance, when
%1
is empty and you doif not hello==%1 call :sub
the command processor will see thisif not hello== call :sub
and comparehello
tocall
then try to execute:sub
, and throw an error. In that specific caseif not xhello==x%1 call :sub
is just as good asif not "hello"=="%1" call :sub
, because an empty%1
will cause the command processor to seeif not xhello==x call :sub
.BUT using characters other than double-quotes will cause problems if the variable contains any special characters.
Using brackets as variable delimiters like (%1) can cause problems. For instance, the (special) piping characters don’t play nice inside brackets, and the escape character just seems to disappear, neither acting as a normal character, nor as the escape-character.
Also brackets are special characters in and of themselves designed to group and/or separate different lines of code and may not always act as anticipated.
Lastly, double quotes themselves are special characters specifically designed to surround other special characters, allowing them to act as normal characters. This is why you may see variables unquoted, then quoted again, like so.
set var="%~1" & REM This sort of thing is used to insure that a variable is quoted. REM %~1 unquotes %1 if it is already quoted, and leaves it alone if REM %1 is not quoted. set "var=%~1" & REM This code assumes that `%1` contains special characters and REM like before unquotes a quoted %1, but leaves the variable itself REM unquoted. The double-quotes surrounding the variable and data REM protects the command processor from any special characters that REM exist in the data. Remember that anytime you reference `%var%`, REM you will need to also surround the variable and data with REM double-quotes.
A quick check for quotes is
if exist %1 if %1==%~1 echo Unquoted
.
–jeroen