La solución de jeb funciona muy bien. Pero puede no ser apropiado en todas las circunstancias. Tiene 2 inconvenientes potenciales:
1) El error de sintaxis se detendrá todo el procesamiento de lote. Entonces, si un script por lotes llamó a su script, y su script se detuvo con el error de sintaxis, entonces el control no se devuelve al llamador. Eso podría ser malo.
2) Normalmente, hay un ENDLOCAL implícito para cada SETLOCAL cuando finaliza el procesamiento por lotes. Pero el error de sintaxis fatal termina el procesamiento por lotes sin el ENDLOCAL implícito! Esto puede tener consecuencias desagradables :-(ver mis DosTips publicar SETLOCAL continues after batch termination! para más información.
actualización 2015-03-20Ver https://stackoverflow.com/a/25474648/1012053 de una forma limpia de terminar inmediatamente todo el procesamiento por lotes.
La otra forma de detener un archivo por lotes dentro de una función es usar el comando EXIT, que saldrá por completo del shell de comandos. Pero un poco de uso creativo de CMD puede hacer que sea útil para resolver el problema.
@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
Tengo tanto mi versión llamada "daveExit.bat" y la versión de Jeb llamado "jebExit.bat" en mi PC.
luego ponerlos a prueba el uso de este script por lotes
@echo off
echo before calling %1
call %1
echo returned from %1
Y aquí están los resultados
>test jebExit
before calling jebExit
hello
stop
>test daveExit
before calling daveExit
hello
stop
returned from daveExit
>
Una desventaja potencial de la solución de salida es que los cambios en el medio ambiente no se conservan. Que pueden ser resueltos en parte por escribir el environent en un archivo temporal antes de salir, y luego leerlo de nuevo.
@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
Pero variables con carácter de nueva línea (0x0A) en el valor no se conservan adecuadamente.
posible duplicado de [escritura de la hornada salida desde el interior de una función] (http://stackoverflow.com/questions/3227796/exit-batch-script- from-inside-a-function) – Nathan