what does ":2" mean in set variable in batch file

Viewed 375

I have this line in my batch file @SET %~1=%~$PATH_VARNAME:2. I don't see what ":2" stands for

more details:

@SET PATH_VARNAME=!%~3! 
@IF NOT DEFINED PATH_VARNAME SET PATH_VARNAME=%PATH%

@SET %~1=%~$PATH_VARNAME:2

%~1 and %~3 are ARGV arguments. when I ECHO %~1 after the last set it shows me C:\Mycomuter\currentdir\example\interface\SET_LIB_PERL_GENE_CSV.bat

C:\Mycomuter\currentdir\example\interface\ is the first path in %PATH% environment variable and SET_LIB_PERL_GENE_CSV.bat is the second ARGV argument

what does this line %~$PATH_VARNAME:2 means, does take the first path of PATH_VARNAME and concatenate it with the second argument of .bat file (SET_LIB_PERL_GENE_CSV.bat) ?

Best regards

2 Answers
set "path_varname=%~dp0"
call :test myvar "%~nx0"
echo(%myvar%
exit /b

:test
set "%~1=%~$PATH_VARNAME:2"

Search for %~2 in %PATH_VARNAME% and set the value to %~1.

The example will search for %~2 which is passed %~nx0 (script name) in %path_name% (script directory) and assigns the value to %~1 (myvar).

The result is displayed with echo(%myvar% which will be the full path to the script.

See for /? at the bottom that mentions:

%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I 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

PATH can be any valid variable with a path(s).

Some more in depth informations:

The syntax %~$PATH:I is rarley used, but it has some unexpected behavior.

Behavior in batch files

Simple percent version %~$PATHVARIABLE:<NUMBER>

  • Only the numbers 0-9 are allowed, else a syntax error is thrown
  • It expands to nothing if the filename in can't be found in any of the pathes in PATHVARIABLE
  • The numbers 0-9 are ALWAYS defined, when they are not set they are empty and the expansion results into nothing
  • As a side effect, the for-variable $ can't be used with ~:
    FOR %%$ in (1) do echo %%~dp$ fails

myBatch.bat myBatch.bat myBatch

@echo off 
set myPathVar=.
echo #0 %~$myPathVar:0
echo #1 %~$myPathVar:1
echo #2 %~$myPathVar:2
echo #3 %~$myPathVar:3
echo #4 %~$myPathVar:*

Output:

#0 C:\Temp\myBatch.bat  
#1 C:\Temp\myBatch.bat  
#2  
#3
The following usage of the path operator in batch-parameter
substitution is invalid: %~$myPathVar:*

FOR-variable version %%~$PATHVARIABLE:<for-variable>

  • All variable names are allowed
  • The expression is discarded and used literally, when the variable is not defined
  • The numbers 0-9 are used only from the for-variables, not from script arguments

FOR-variable detection

This can be used for detection, if a FOR-variable is already used (All for-variables are stored in a global FOR-variable-store).

@echo off 

FOR %%X in (test) do call :func
exit /b

:func

for %%1 in (one) do (
    if "%%~$=undef=:1" =="" echo varaible-1 is defined
    if "%%~$=undef=:2" =="" echo varaible-2 is defined
    if "%%~$=undef=:X" =="" echo varaible-X is defined
    if "%%~$=undef=:Y" =="" echo varaible-Y is defined
)

This outputs, that 1 and X are defined.

In this test =undef= is used as variable that is always undefined, therefore there is no path to be searched and the expansion can only be empty.

Disappearing quotes

This can also be used for disappearing quotes, this are quotes that quotes the line, but doesn't appear in the output.

FOR %%# in (test) DO (
  echo %%~$="=:# Disappearing quote, supports &<>| without ^ escaping
)

Percent delimiter

%%~$=undef=:X can be used to separate percent signs and characters, useful to echo literals, like %X

FOR %%X in (TEST) DO (
    echo Output [percent][X] %%X -- fails, expands to TEST
    echo Output [percent][X] %%%%~$=undef=:XX
)

Behavior in command line context

Simple percent version %~$PATHVARIABLE:<NUMBER>

  • Never works, because there is no valid NUMBER
  • The expression always remains unchanged

FOR-variable version %~$PATHVARIABLE:<for-variable>

  • There is only one percent sign
  • Works like in a batch file
Related