call 是一个非常重要且常用的命令,尤其是在批处理脚本(.bat 或 .cmd)中,它的核心作用是从一个脚本中调用另一个脚本或程序,并在调用结束后返回到原脚本的下一行继续执行。

call 命令的基本语法
call [Drive:][Path] FileName [BatchParameters]
[Drive:][Path] FileName:这是必需的参数,指定你要调用的批处理文件(.bat或.cmd)或可执行文件(.exe,.com等)的完整路径或相对路径。[BatchParameters]:这是可选参数,传递给被调用脚本的命令行参数。
call 命令的核心作用与重要性
为了理解 call 的必要性,我们必须先了解在批处理脚本中,直接运行另一个脚本会发生什么。
场景:不使用 call 命令
假设你有两个文件:
main_script.bat:
@echo off echo 这是主脚本开始... echo 准备调用子脚本... sub_script.bat echo 子脚本调用完毕,返回主脚本。 echo 主脚本结束。 pause
sub_script.bat:

@echo off echo 这是子脚本,正在执行... echo 子脚本结束。
当你运行 main_script.bat 时,控制台输出如下:
这是主脚本开始...
准备调用子脚本...
这是子脚本,正在执行...
子脚本结束。
主脚本结束。
请按任意键继续. . .
问题所在:你会发现 echo 子脚本调用完毕,返回主脚本。 这一行没有被执行,这是因为 main_script.bat 在执行到 sub_script.bat 时,整个 main_script.bat 的进程被 sub_script.bat 的进程取代了,当 sub_script.bat 运行完毕后,它的进程结束,而原来的 main_script.bat 进程已经不存在了,所以无法“返回”继续执行。
场景:使用 call 命令
我们修改 main_script.bat,在调用 sub_script.bat 前面加上 call:
main_script.bat:
@echo off echo 这是主脚本开始... echo 准备调用子脚本... call sub_script.bat echo 子脚本调用完毕,返回主脚本。 echo 主脚本结束。 pause
再次运行 main_script.bat,控制台输出如下:
这是主脚本开始...
准备调用子脚本...
这是子脚本,正在执行...
子脚本结束。
子脚本调用完毕,返回主脚本。
主脚本结束。
请按任意键继续. . .
结果:这次所有命令都按顺序执行了。call 命令确保了在 sub_script.bat 执行完毕后,控制权会返回到 main_script.bat,继续执行 call 语句后面的代码。
call 命令的其他重要用法
除了调用其他脚本,call 还有两个非常实用的功能。
A. 调用带参数的脚本
call 可以方便地向被调用的脚本传递参数。
caller.bat:
@echo off echo 准备调用一个带参数的脚本... call argument_script.bat Hello World 123 echo 调用完成。 pause
argument_script.bat:
@echo off echo 第一个参数是: %1 echo 第二个参数是: %2 echo 第三个参数是: %3
运行 caller.bat 的输出:
准备调用一个带参数的脚本...
第一个参数是: Hello
第二个参数是: World
第三个参数是: 123
调用完成。
请按任意键继续. . .
B. 调用标签(实现脚本内子程序)
这是 call 一个非常强大但常被忽略的功能,你可以使用 call 来调用脚本内部的“标签”,从而实现类似函数或子程序的代码复用。
procedure_demo.bat:
@echo off echo 主脚本开始 call :my_subroutine "这是一个传递给子程序的参数" echo 返回主脚本,继续执行... call :another_subroutine echo 主脚本结束。 pause exit /b :my_subroutine echo --- 进入子程序 my_subroutine --- echo 收到的参数是: %~1 echo --- 退出子程序 my_subroutine --- goto :eof :another_subroutine echo --- 进入子程序 another_subroutine --- echo 这个子程序没有参数。 echo --- 退出子程序 another_subroutine --- goto :eof
输出结果:
主脚本开始
--- 进入子程序 my_subroutine ---
收到的参数是: "这是一个传递给子程序的参数"
--- 退出子程序 my_subroutine ---
返回主脚本,继续执行...
--- 进入子程序 another_subroutine ---
这个子程序没有参数。
--- 退出子程序 another_subroutine ---
主脚本结束。
请按任意键继续. . .
关键点解释:
my_subroutine:定义了一个名为my_subroutine的标签。call :my_subroutine ...:调用这个标签。call确保在标签执行到goto :eof(文件的结尾)后,会返回到call语句的下一行。exit /b:在脚本主逻辑结束后使用,可以防止脚本意外执行到标签定义的代码。goto :eof:这是一个特殊的命令,表示 "Go To the End of the File"(跳转到文件结尾),它会结束当前批处理文件的执行,并返回给调用者,在子程序中,它起到了return的作用。
何时应该使用 call ?
- 调用另一个批处理文件(.bat/.cmd)时:必须使用
call,否则无法返回。 - 调用一个标签(实现子程序)时:必须使用
call。 - 调用一个普通的可执行文件(.exe, .com, .msi 等)时:通常不需要使用
call,因为可执行文件运行完后会自动返回控制权,不会取代当前批处理进程。notepad.exe和call notepad.exe在效果上几乎是一样的(除了极少数情况下的环境变量继承问题)。- 如果你希望脚本在
notepad.exe关闭后继续执行,不加call也是可以的,为了代码清晰,很多人习惯在调用外部程序时也加上call,但这不是强制要求。
call 与 start 命令的区别
call 和 start 都可以用来运行其他程序,但它们的行为完全不同:
| 特性 | call |
start |
|---|---|---|
| 核心功能 | 调用并等待返回,调用者会暂停,直到被调用者执行完毕。 | 启动并继续,调用者会立即继续执行下一行,不等待被启动的程序。 |
| 进程关系 | 被调用者在同一进程中运行(对于批处理文件而言)。 | 被启动者通常在新进程中运行。 |
| 主要用途 | 执行顺序逻辑、调用子程序。 | 并行任务、打开新窗口/新会话运行程序。 |
| 示例 | call script.bat (等待 script.bat 结束) |
start notepad.exe (立即打开记事本,脚本继续往下走) |
call的核心是“返回”,它解决了在批处理脚本中调用另一个脚本后无法返回原脚本继续执行的问题。- 调用
.bat或.cmd文件时,几乎总是需要call。 - 使用
call可以在脚本内部实现类似函数的子程序,提高代码的模块化和复用性。 - 调用
.exe等外部程序时,通常不需要call,但加上也无妨,能确保行为一致。 call和start是两个完全不同的命令,call用于顺序执行,start用于并行执行。
掌握 call 命令是编写结构清晰、功能强大的批处理脚本的关键一步。
