WOW - That certainly is unexpected behavior. I checked and you get the same behavior if executed from the command line.
It took me a while to figure out your point. I modified your test script to make the point more obvious: Invoking an internal command directly ignores any files of that name that happen to be lying around. But CALLing an internal command fails if an executable file exists with the same name. (I fixed and improved this example after jeb's next post below)And fixed this once again
Code: Select all
echo @echo *** External batch %%~nx0, parameters are '%%*'
) > SET.BAT
copy set.bat SET2.BAT >nul
call SET varCall=hello
call :SET :label ignores files
call SET2 Testing call to SET2
call :SET2 Testing call to :SET2
call ECHO Testing call to ECHO
call :ECHO Testing call to :ECHO
call UNIQUE_CALL Testing call to UNIQUE_CALL
call :UNIQUE_CALL Testing call to :UNIQUE_CALL
echo GOTO UNIQUE_GOTO worked without the colon
echo Called label %0, parameters are '%*'
Code: Select all
*** External batch SET.BAT, parameters are 'varCall=hello'
Called label :SET, parameters are ':label ignores files'
Environment variable varCall not defined
*** External batch SET2.BAT, parameters are 'Testing call to SET2'
Called label :SET2, parameters are 'Testing call to :SET2'
Testing call to ECHO
Called label :ECHO, parameters are 'Testing call to :ECHO'
'UNIQUE_CALL' is not recognized as an internal or external command,
operable program or batch file.
Called label :UNIQUE_CALL, parameters are 'Testing call to :UNIQUE_CALL'
GOTO UNIQUE_GOTO worked without the colon
This also helps explain why calling a :label can be faster than calling a command. The command wastes time scanning all directories in PATH for a (hopefully) non-existent executable file. But the call to a :label immediately looks for the label without bothering to scan for a file.
Summary of CALL processing sequence from within a batch file:
A) CALL TEXT
- 1 - Look for executable file named TEXT
- 2 - Try TEXT as an internal command
B) CALL :TEXT
- 1 - Look for label named :TEXT
Unrelated) GOTO :LABEL (with colon) and GOTO LABEL (without colon) both work the same. But CALL LABEL (without colon) does not work.
jeb wrote:So call is not only slow it's also unsafe, as you can't know if it works.
Especially if you fail to delete that nasty SET.BAT that was created in your example.