Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

(Very) Small Difference in Batch Parameters %* and %$

Dec
20
2
$* the complete command tail, unmodified by SHIFT
%$ the complete command tail, modified by SHIFT

We do not uses SHIFT very often so we mixed up these two parameters.

On one occasion its was fatal..

It is a minor issue with a very easy workaround.

[R:\] type SetPath.btm setlocal echo TCCVer=%@verinfo[%_cmdspec,Fileversion] OSBuild=%_OSBuildEx set path_to_added=C:\ ECHO. ECHOX %$ the complete command tail, modified by SHIFT ALIAS SETPATH=SET PATH=`C:\Windows;%$` SETPATH %path_to_added ECHO PATH=%PATH PATH/N PATH/V ECHO. ECHOX %* the complete command tail, unmodified by SHIFT ALIAS SETPATH=SET PATH=`C:\Windows;%*` SETPATH %path_to_added ECHO PATH=%PATH PATH/N PATH/V [R:\] call SetPath.btm TCCVer=28.02.18 OSBuild=22000.376 %$ the complete command tail, modified by SHIFT PATH=C:\Windows;C:\ C:\Windows C:\ %* the complete command tail, unmodified by SHIFT PATH=C:\Windows; C:\ C:\Windows C:\ TCC: (Sys) R:\SetPath.btm [20] The system cannot find the path specified. " C:\"

The extra space before C invalidates the PATH.
We do not use SHIFT and expected the two batch parameters are exactly the same.
 
Can reproduce that with following:

Code:
@echo off

echo.
set toadd=C:\
echox %$ The complete command tail, modified by SHIFT
alias testalias1=set testvar1=`C:\Windows;%$`
testalias1 %toadd
echo testvar1=%testvar1
unalias testalias1
unset toadd
unset testvar1

echo.
set toadd=C:\
echox %* The complete command tail, unmodified by SHIFT
alias testalias1=set testvar1=`C:\Windows;%*`
testalias1 %toadd
echo testvar1=%testvar1
unalias testalias1
unset toadd
unset testvar1

Code:
%$ The complete command tail, modified by SHIFT
testvar1=C:\Windows;C:\

%* The complete command tail, unmodified by SHIFT
testvar1=C:\Windows; C:\

EDIT: However, with the first try, the command tail doesn't work!
EDIT2: Replaced example with better code ...
 
Last edited:
Seems it's realated to ALIAS, because in the following example, BOTH have a leading space:

Code:
@echo off

set toadd=C:\

echo.
echox %$ The complete command tail, modified by SHIFT
set testvar1=`C:\Windows;%$` %toadd
echo testvar1=%testvar1
echo.
echox %* The complete command tail, unmodified by SHIFT
set testvar1=`C:\Windows;%*` %toadd
echo testvar1=%testvar1

Code:
%$ The complete command tail, modified by SHIFT
testvar1=C:\Windows; C:\

%* The complete command tail, unmodified by SHIFT
testvar1=C:\Windows; C:\

EDIT: NOT TRUE, was only because not unset related var(s).
 
Last edited:
Code:
@echo off
setlocal

alias `test1=echo "%$"`
alias `test2=echo "%*"`

echo These two aliases look similar, but they do very different things.
echo TEST1 echos ITS OWN parameters, in quotes:
echo.

test1 One two three

echo.
echo But TEST2 echos any BATCH FILE'S parameters, in quotes, followed
echo by its own, if any:
echo.

test2 One two three

echo.
echo Try calling this batch files with different parameters to see how
echo this works.
echo.

endlocal
 
I'm going to explain this again, in a different way. In an alias, %$ expands to the alias's parameters. %* is always and only batch file parameters; it has no special meaning to the alias mechanism.

If an alias definition does not explicitly refer to its parameters with %$ (or %1, %1$, whatever), they will get tacked on automatically, with a space separator. That's where that mysterious space is coming from.

Code:
C:\>alias foo=`echo !`

C:\>foo
!

C:\>foo bar baz quux
! bar baz quux

C:\>

If you don't want this to happen, you can add a REM to the end to 'swallow' the unwanted args:

Code:
C:\>alias foo=`echo ! & rem`

C:\>foo
!

C:\>foo bar baz quux
!

C:\>
 
Last edited:
So, I think an easy methode could be something like that (not changed the path real, just as example):

Code:
type SetPathTest.btm

@echo off

set PathToAdd=C:\

echo.

set SetPathVar=`C:\Windows;%PathToAdd;%*`

echo SetPathVar: %SetPathVar

unset PathToAdd
unset SetPathVar

Code:
SetPath.btm

SetPathVar: C:\Windows;C:\;


SetPath.btm Test

SetPathVar: C:\Windows;C:\;Test
 
If you don't want this to happen, you can add a REM to the end to 'swallow' the unwanted args:
It is a good idea to do that with aliases that copy, move, or erase files, since otherwise, if you forget to press Enter and type some more stuff after the alias, your files may get messed up.
 
"Very easy methode" is to never ever use "%*" - it is only included for compatibility with cmd and is nearly useless.
 

Similar threads

Back
Top