Windows package: cannot exit the called subroutine - always returns, even if goto: END

I have subroutines called to check ERRORLEVEL

.
The routine calls other routines to log messages, send email, and then exit the script. It goes to :END

, then returns to stmt after calling

@echo off
echo starting...
call:checkTime
echo +++ after CT
GOTO:END

:checkTime
echo the time is %TIME%
goto:END
goto:EOF

:END

      

+3


source to share


2 answers


The question is poorly phrased, but I think I understand (especially when focusing on the title)

My interpretation of your problem:

At various points in your batch file, you check the ERRORLEVEL. Whenever you encounter an error, you want to do some standard error handling and then exit the batch script. You tried to create a routine to do standard processing, but the routine returns to the caller instead of exiting the script. Your question is, how do you force your error handling routine to exit rather than returning to the caller?

Answer:

If none of your error detections occur in the called subroutine, you can simply use GOTO for your error processor instead of CALLing it.

If you want to be able to call a subroutine and exit from another called subroutine, you can continue using the statement CALL

, but end your error procedure with EXIT

instead of GOTO :EOF

or GOTO :END

.



Adding in response to a comment

Yes, GOTO cannot pass parameters and the CALLed subroutine will always return to the caller (unless the procedure ends with EXIT)

And yes, EXIT will close the current CMD shell, which would normally close the console window.

BUT ... you can run the batch file through another CMD shell so that EXIT doesn't close the window!

The only potential downside to this I see is the changes to the environment, which will be lost after the batch file (and the CMD shell that launches it) finishes. This may or may not be a problem for you.

@echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
exit /b

:main
shift /1
echo %%1=%1  %%2=%2

echo before call
call :exitRoutine
:: should not get here
echo after call
exit /b

:exitRoutine
echo exiting batch file witin exitRoutine
exit

      

+3


source


Yes, this is the expected behavior: a subroutine called via a command CALL

can end in three different ways: execution EXIT [/B]

, execution, GOTO :EOF

or simply reaching the end of the file. All three methods fall back to the calling program. By then, the "GOTO" command now accepts a target: EOF label, which transfers control to the end of the current script batch. This is an easy way to exit a batch script without defining a label. "(from GOTO /?

), so really the second and third methods are the same.

If you want to return from a subroutine sometimes, but at other times to terminate the calling program, your subroutine can NOT be executed using CALL

, but in a different way. If you want to pass parameters to a subroutine, then it must be a separate .BAT file that will be executed through its name with parameters and a NO call, for example:

subprogram param1 param2 ...

      

Thus, for this routine to "return" to the caller, it must know which batch file and on which line it must return. This information can be set by the calling program via variables; The caller must also determine if it is being executed normally or because of a false subroutine return. You can do it like this:

main.bat:



@echo off
rem If this is a false subroutine return: complete it
if "%1" == "return" goto %2
rem Do my usual business
rem . . .
rem Execute the subprogram as subroutine
set caller=main
set returnPoint=label23
subprogram param1 param2
:label23
rem Continue after subprogram return...

      

subprogram.bat:

rem Do my business
rem . . .
rem To return to the caller:
%caller% return %returnPoint%
rem . . .
rem To terminate here, execute EXIT /B, GOTO :EOF, or just reach the end

      

Sorry, there is no easy way to do this ...

+2


source







All Articles