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 againCode: Select all
@echo off
setlocal
(
echo @echo *** External batch %%~nx0, parameters are '%%*'
) > SET.BAT
copy set.bat SET2.BAT >nul
set "varCall="
set "varDirect="
set varDirect=goodbye
call SET varCall=hello
call :SET :label ignores files
set varCall
set varDirect
echo(
call SET2 Testing call to SET2
call :SET2 Testing call to :SET2
echo(
call ECHO Testing call to ECHO
call :ECHO Testing call to :ECHO
echo(
call UNIQUE_CALL Testing call to UNIQUE_CALL
call :UNIQUE_CALL Testing call to :UNIQUE_CALL
del set.bat
del set2.bat
goto UNIQUE_GOTO
exit /b
:UNIQUE_GOTO
echo GOTO UNIQUE_GOTO worked without the colon
exit /b
:SET
:SET2
:ECHO
:UNIQUE_CALL
echo Called label %0, parameters are '%*'
exit /b
Output:
Code: Select all
*** External batch SET.BAT, parameters are 'varCall=hello'
Called label :SET, parameters are ':label ignores files'
Environment variable varCall not defined
varDirect=goodbye
*** 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.
Dave Benham