The CALL statement was introduced in MS-DOS 3.3
It is used to call other batch files within a batch file, without aborting the execution of the calling batch file, and using the same environment for both batch files.
Say you have a batch file named BATCH1.BAT, which needs to execute a second batch file named BATCH2.BAT.
Let's say BATCH1.BAT looks like this:
REM Batch1.bat SET ABC=1 CALL BATCH2.BAT %ABC% ECHO ABC = %ABC% BATCH2.BAT %ABC% ECHO ABC = %ABC%
And BATCH2.BAT looks like this:
REM Batch2.bat SET ABC=%ABC%%1
Running BATCH1.BAT will display something like this:
C:\>batch1.bat C:\>REM Batch1.bat C:\>SET ABC=1 C:\>CALL BATCH2.BAT 1 C:\>REM Batch2.bat C:\>SET ABC=11 C:\> C:\>ECHO ABC = 11 ABC = 11 C:\>BATCH2.BAT 11 C:\>REM Batch2.bat C:\>SET ABC=1111 C:\> C:\>
You see? The second run of BATCH2.BAT (without the CALL statement) aborts the "calling" batch file. The last line of BATCH1.CMD (
ECHO ABC = %ABC%) isn't executed.
Until CALL was introduced, the only way to run another batch file and return to the calling batch file was
That would result in BATCH1.BAT looking like this:
REM Batch1.bat SET ABC=1 COMMAND /C BATCH2.BAT %ABC% ECHO ABC = %ABC% BATCH2.BAT %ABC% ECHO ABC = %ABC%
Running BATCH1.BAT again will now result in something like this:
C:\ batch1.bat C:\>REM Batch1.bat C:\>SET ABC=1 C:\>COMMAND /C BATCH2.BAT 1 C:\>REM Batch2.bat C:\>SET ABC=11 C:\> C:\>ECHO ABC = 1 ABC = 1 C:\>BATCH2.BAT 1 C:\>REM Batch2.bat C:\>SET ABC=11 C:\> C:\>
Note the parts marked red, this shows that although BATCH2.BAT altered the variable ABC, this alteration wasn't returned to the calling batch file. That's because the newly started COMMAND.COM has its own separate environment, which is flushed when COMMAND.COM is closed. The newly started COMMAND.COM did, however, inherit the environment of the calling batch file, including the ABC variable.
It's amazing we ever managed to do anything in batch before MS-DOS 3.3
In Windows NT 4/Windows 2000, CALL not only calls other batch files, it can also call subroutines within the same batch file.
All it takes is a colon (:) before the subroutine's name (in fact, this is a normal batch label), as in
CALL :Whatever or
CALL:Whatever, and the subroutine has to end with
GOTO :EOF or
GOTO:EOF acts as the "return" in most other languages.
Parameters are the same as for "external" batch files: %1 %2 ... %9, %*.
@ECHO OFF REM The main "program" calls the Subroutine once for every Domain Admin: FOR /F "tokens=*" %%A IN ('NET GROUP "Domain Admins" /DOMAIN ˆ| FIND " "') DO CALL :Subroutine %%A GOTO:EOF :Subroutine REM Display user ID and Full Name for specified Domain Admin: FOR %%B IN (%*) DO ( ECHO User Name %%B NET USER %%B /DOMAIN | FIND "Full Name" ECHO. ) GOTO:EOF
More examples can be found in CvtUrlNT.bat, FileSys.bat, KillDisc.bat (Advanced Version) and Which.bat.