jebのソリューションはうまく機能します。しかし、すべての状況で適切であるとは限りません。潜在的な欠点が 2 つあります。
1) 構文エラーにより、すべてのバッチ処理が停止します。したがって、バッチ スクリプトがスクリプトを呼び出し、スクリプトが構文エラーで停止した場合、制御は呼び出し元に返されません。それは悪いかもしれません。
2) 通常、バッチ処理が終了すると、すべての SETLOCAL に対して暗黙の ENDLOCAL が存在します。しかし、致命的な構文エラーにより、暗黙の ENDLOCAL !なしでバッチ処理が終了します。これは厄介な結果をもたらす可能性があります :-( 詳細については、DosTips のポスト「バッチ終了後に SETLOCAL が続行されます! 」を参照してください。
更新 2015-03-20 すべてのバッチ処理をすぐに終了するクリーンな方法については、https: //stackoverflow.com/a/25474648/1012053を参照してください。
関数内でバッチ ファイルを停止するもう 1 つの方法は、コマンド シェルを完全に終了する EXIT コマンドを使用することです。しかし、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 ソリューションの潜在的な欠点の 1 つは、環境への変更が保持されないことです。これは、終了する前に環境を一時ファイルに書き込んでから読み戻すことで部分的に解決できます。
@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) を含む変数は適切に保持されません。