Exit batch file from subroutine

Add this to the top of your batch file:

@ECHO OFF
SETLOCAL

IF "%selfWrapped%"=="" (
  REM this is necessary so that we can use "exit" to terminate the batch file,
  REM and all subroutines, but not the original cmd.exe
  SET selfWrapped=true
  %ComSpec% /s /c ""%~0" %*"
  GOTO :EOF
)

Then you can simply call:

  • EXIT [errorLevel] if you want to exit the entire file
  • EXIT /B [errorLevel] to exit the current subroutine
  • GOTO :EOF to exit the current subroutine

How about this one minor adjustment?

@echo off
ECHO Quitting...
CALL :QUIT
:: The QUIT subroutine might have set the error code so let's take a look.
IF ERRORLEVEL 1 GOTO :EOF
ECHO Still here!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0

Output:

Quitting...

Technically this doesn't exit from within the subroutine. Rather, it simply checks the result of the subroutine and takes action from there.


This will exit current context and a parent context (i.e., when executed inside a one call deep subroutine script will exit):

(goto) 2>nul || exit /b

Or, if you need errorlevel 0:

(goto) 2>nul || (
    type nul>nul
    exit /b
)

Basically, (goto) 2>nul sets errorlevel to 1 (without outputting an error), returns execution to the parent context and code after double pipe is executed in parent context. type nul>nul sets errorlevel to 0.

UPD:

To return execution more than twice in a row, chain several (goto) 2>nul || like this:

(goto) 2>nul || (goto) 2>nul || (goto) 2>nul || (
    type nul>nul
    exit /b
)

Here's a recursive subroutine to return context a variable number of times:

:Kill
(goto) 2>nul || (
    set /a depth=%1-1
    if %1 GEQ 1 (
        call:Kill !depth!
    )
    (goto) 2>nul || (type nul>nul)
)

When called from a recursive function:

@echo off
setlocal EnableDelayedExpansion
call:Recurs 5
echo This won't be printed
exit /b

:Recurs
set /a ri+=1
echo %ri%
if %ri% LSS %1 (
    call:Recurs %1
)
echo This will be printed only once
call:Kill %1
exit /b

the output will be:

1
2
3
4
5
This will be printed only once