Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I exit a batch file from inside a subroutine?

If I use the EXIT command, I simply return to the line where I called the subroutine, and execution continues.

Here's an example:

@echo off
ECHO Quitting...
CALL :QUIT
ECHO Still here!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0

Output:

Quitting...
Still here!


Update:

This isn't a proper answer, but I ended up doing something along the lines of:

@echo off
CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL
ECHO You shouldn't see this!
GOTO END

:SUBROUTINE_WITH_ERROR
ECHO Simulating failure...
EXIT /B 1

:HANDLE_FAIL
ECHO FAILURE!
EXIT /B 1

:END
ECHO NORMAL EXIT!
EXIT /B 0

The double-pipe statement of:

CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL

is shorthand for:

CALL :SUBROUTINE_WITH_ERROR 
IF ERRORLEVEL 1 GOTO HANDLE_FAIL

I would still love to know if there's a way to exit directly from a subroutine rather than having to make the CALLER handle the situation, but this at least gets the job done.


Update #2: When calling a subroutine from within another subroutine, called in the manner above, I call from within subroutines thusly:

CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1

This way, the error propagates back up to the "main", so to speak. The main part of the batch can then handle the error with the error handler GOTO :FAILURE

share|improve this question

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
share|improve this answer
    
+1 Perfect solution! – U-D13 Jul 7 '11 at 23:54
    
+1 for actually mentioning GOTO :EOF – afrazier Dec 7 '11 at 22:06
    
Very nice. I've made a small modification, assign %~0 to the variable instead of true: if not "%selfwrapped%"=="%~0" ( set selfwrapped=%~0 .... ). That way you can use the same trick in multiple batch scripts that call each other. – GolezTrol Jul 27 '15 at 20:41

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.

share|improve this answer
2  
Thanks, that would certainly get the job done, and if I can't find a better answer that's what I'll have to do. However, I'd rather not have to paste that line after every CALL in my long and complex batch file. – Brown Dec 8 '09 at 18:47

If you do not want to come back from the procedure, don't use call: instead use goto.

@echo off
ECHO Quitting...
GOTO :QUIT
ECHO Will never be there!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0
share|improve this answer
    
The point of the question is how to do it from subroutines (i.e. using call) so this doesn't answer it. – Steve Crane Nov 19 '13 at 10:15

I put error handling in my batch files. You can call error handlers like this:

CALL :WARNING "This is" "an important" "warning."

And here is the end of the batch file:

::-------------------------------------------------------------------
::  Decisions
::-------------------------------------------------------------------
:INFO
IF "_DEBUG"=="true" (
  ECHO INFO: %~1
  IF NOT "%~2"=="" ECHO          %~2
  IF NOT "%~3"=="" ECHO          %~3
)
EXIT /B 0
:WARNING
ECHO WARNING: %~1
IF NOT "%~2"=="" ECHO          %~2
IF NOT "%~3"=="" ECHO          %~3
EXIT /B 0
:FAILURE
ECHO FAILURE: %~1
IF NOT "%~2"=="" ECHO          %~2
IF NOT "%~3"=="" ECHO          %~3
pause>nul
:END
ECHO Closing Server.bat script
FOR /l %%a in (5,-1,1) do (TITLE %TITLETEXT% -- closing in %%as&PING.exe -n 2 -w 1 127.0.0.1>nul)
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .