How can I exit a batch file from a function?

I have a simple function written to check directories:

:direxist if not exist %~1 ( echo %~1 could not be found, check to make sure your location is correct. goto:end ) else ( echo %~1 is a real directory goto:eof ) 

: end is written as

 :end endlocal 

I do not understand why the program does not stop after goto: end has been called. I have another function that uses the same method to stop the program, and it works fine.

 :PRINT_USAGE echo Usage: echo ------ echo <file usage information> goto:end 

In this case, the program stops after a call: end; why it doesn't work: direxist? Thanks for the help!

+8
batch-file goto exit
source share
4 answers

I assume that you are mixing call and goto .

The label in the batch file can be used with call or goto , but the behavior is different.
If you call such a function, it will return when the function reaches the end of the file or explicit exit /b or goto :eof (for example, your goto :end ).

Therefore, you cannot cancel your batch if you use the label as a function.

However, goto on the shortcut will not return to the caller.

But there is also a way out of the party from the function.
You can create a syntax error, this will cause the package to stop.

 @echo off call :label hello call :label stop echo Never returns exit /b :label echo %1 if "%1"=="stop" goto :halt exit /b :halt call :haltHelper 2> nul :haltHelper () exit /b 
+12
source share
Decision

jeb works great. But this may not be acceptable under any circumstances. It has 2 potential disadvantages:

1) A syntax error will stop all batch processing. Therefore, if the script package is called your script, and your script is stopped with a syntax error, control is not returned to the caller. It could be bad.

2) Normally there is an implicit ENDLOCAL for each SETLOCAL when batch processing completes. But a fatal syntax error completes batch processing without implicit ENDLOCAL ! This can have unpleasant consequences: - (See My DosTips SETLOCAL post continues after batch completion! For more information.

Update 2015-03-20 See https://stackoverflow.com/a/166778/ for more info on how to immediately complete all batch processing.

Another way to stop the batch file inside the function is to use the EXIT command, which will exit the shell completely. But a little creative use of CMD can make it useful to solve the problem.

 @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 

I have both my version with the name "daveExit.bat" and the jeb version with the name "jebExit.bat" on my PC.

Then I test them using this script package

 @echo off echo before calling %1 call %1 echo returned from %1 

And here are the results

 >test jebExit before calling jebExit hello stop >test daveExit before calling daveExit hello stop returned from daveExit > 

One of the potential drawbacks of the EXIT solution is that changes to the environment are not saved. This can be partially solved by writing the medium to a temporary file before exiting, and then reading it again.

 @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 

But variables with a newline character (0x0A) in the value will not be stored properly.

+5
source share

Here is my solution that will support nested procedures if everyone is checked for error level I add a test for errolevel in all my calls (internal or external)

 @echo off call :error message&if errorlevel 1 exit /b %errorlevel%< @echo continuing exit /b 0 :error @echo in %0 @echo message: %1 set yes= set /p yes=[no]^|yes to continue if /i "%yes%" == "yes" exit /b 0 exit /b 1 
+1
source share

If you use exit /b X to exit the function, then it will set ERRORLEVEL to X Then you can use || conditional processing character to execute the command if ERRORLEVEL not zero.

 @echo off setlocal call :myfunction PASS || goto :eof call :myfunction FAIL || goto :eof echo Execution never gets here goto :eof :myfunction if "%1"=="FAIL" ( echo myfunction: got a FAIL. Will exit. exit /b 1 ) echo myfunction: Everything is good. exit /b 0 

Exit from this script:

 myfunction: Everything is good. myfunction: got a FAIL. Will exit. 
+1
source share

All Articles