goto 是干什么的
goto 让批处理跳到指定标签继续执行,是 CMD 里唯一的流程控制手段。它常被用来做“成功走到末尾、失败跳到统一错误分支”的结构,配合 :eof 内置标签还能提前结束脚本或子过程。相比 if 的嵌套,goto 写错误处理更直观,但也更容易因为标签命名混乱而写出难维护的脚本。
基本信息
| 适用平台 | Windows CMD 批处理 |
|---|---|
| 语法 | goto :标签;定义标签用 :标签;goto :eof 结束当前脚本或子过程 |
| 命令扩展 | 默认启用(cmd /e:on),Windows 上均为启用状态 |
| 常用搭配 | if %ERRORLEVEL% GEQ n goto fail;call 与 exit /b 组合 |
典型使用场景
- 统一错误处理:脚本末尾放一个 :fail 分支,集中记录日志与退出码
- 循环结构:用标签加 if 模拟 while 循环
- 提前返回:条件满足时用 goto :eof 直接结束
- 子过程调用:call :sub 执行后返回,便于脚本模块化
- 兼容老逻辑:维护遗留脚本时必须理解 goto 的跳转关系
常用示例
常用示例
@echo off
setlocal
:: 备份并在失败时跳到错误分支
robocopy D:\Src D:\Dst /E
if %ERRORLEVEL% GEQ 8 goto fail
echo 备份成功
goto :eof
:: 错误处理分支
:fail
echo [%date% %time%] 备份失败,错误码 %ERRORLEVEL% >> D:\backup.log
exit /b 1
:: 子过程写法
:sub
echo 在子过程中执行
goto :eof退出码与错误处理
| 项目 | 含义 | 注意点 |
|---|---|---|
| %ERRORLEVEL% | 上一条命令的退出码 | 部分命令不设置,需实测确认 |
| robocopy 特殊 | 0-7 视为成功,8 及以上才是失败 | 用 GEQ 8 判断,不要写成 != 0 |
| exit /b n | 从脚本或子过程返回 | 不带参数则返回 0 |
| goto :eof | 结束当前脚本/子过程 | 无需预先定义标签 |
goto :eof 是内置终点标签,不需要自己定义。它的经典用途是在 call 调用的子过程末尾返回,也在菜单式脚本里充当“结束并退出”的收尾动作。
标签定义时要写成 :fail(带冒号),跳转时写 goto fail(不带冒号)。漏写或写反都会得到“找不到指定的批标签”或直接跳到错误位置,这是新手最常遇到的批处理报错。
两个 bat 文件里有同名标签时,call 进入的子脚本执行 goto 可能跳到调用方的同名标签上,导致难以复现的诡异流程。跨文件复用时给标签加前缀,例如 :svc_start 而不是 :start。