jeb 的解决方案效果很好。但这可能并不适用于所有情况。它有两个潜在的缺点:
1) 语法错误将停止所有批处理。因此,如果批处理脚本调用了您的脚本,并且您的脚本因语法错误而停止,则控制权不会返回给调用者。那可能很糟糕。
2) 通常,当批处理终止时,每个 SETLOCAL 都有一个隐式 ENDLOCAL。但是致命的语法错误会终止批处理没有隐式ENDLOCAL!这可能会产生令人讨厌的后果 :-( 请参阅我的 DosTips 帖子 SETLOCAL continues after batch termination! 了解更多信息。
2015 年 3 月 20 日更新 请参阅 https://stackoverflow.com/a/25474648/1012053,了解立即终止所有批处理的干净方法。
在函数中停止批处理文件的另一种方法是使用 EXIT 命令,该命令将完全退出命令 shell。但是稍微创造性地使用 CMD 就可以帮助解决问题。
@echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
exit /b
:main
call :label hello
call :label stop
echo Never returns
exit /b
:label
echo %1
if "%1"=="stop" exit
exit /b
我的 PC 上既有名为“daveExit.bat”的版本,也有名为“jebExit.bat”的 jeb 版本。
然后我使用这个批处理脚本测试它们
@echo off
echo before calling %1
call %1
echo returned from %1
这是结果
>test jebExit
before calling jebExit
hello
stop
>test daveExit
before calling daveExit
hello
stop
returned from daveExit
>
EXIT 解决方案的一个潜在缺点是不会保留对环境的更改。这可以通过在退出之前将环境写入临时文件,然后再读回来部分解决。
@echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
for /f "eol== delims=" %%A in (env.tmp) do set %%A
del env.tmp
exit /b
:main
call :label hello
set junk=saved
call :label stop
echo Never returns
exit /b
:label
echo %1
if "%1"=="stop" goto :saveEnvAndExit
exit /b
:saveEnvAndExit
set >env.tmp
exit
但值中带有换行符(0x0A)的变量将无法正确保留。