Exit batch script from inside a function

前端 未结 5 669
没有蜡笔的小新
没有蜡笔的小新 2020-12-02 23:57

I have a problem with my batch file. It builds several programs automatically by doing something like this:

  • set some compilation flags
  • run \'gmake all
5条回答
  •  情歌与酒
    2020-12-03 00:23

    For a good solution see the part improved version

    You can stop a batch at any point, also inside of nested function calls.

    You only need to create a syntax error, for example with an empty block (), to suppress the error message, it can be executed in a call, and the stderr of the call is redirected to nul.

    @echo off
    setlocal enabledelayedexpansion
    
    rem Do something
    call :interactive_check
    
    rem Do something
    call :interactive_check
    
    goto :eof
    
    ::::::::::::::::::::::::::
    :interactive_check
    if errorlevel 1 (
        echo.
        echo /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
        echo Error in compilation process... exiting
        echo /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
        call :halt 1
    ) ELSE (
        echo.Continuing to next step
    )
    goto :eof
    
    :: Sets the errorlevel and stops the batch immediately
    :halt
    call :__SetErrorLevel %1
    call :__ErrorExit 2> nul
    goto :eof
    
    :__ErrorExit
    rem Creates a syntax error, stops immediately
    () 
    goto :eof
    
    :__SetErrorLevel
    exit /b %time:~-2%
    goto :eof
    

    2017-04-09 Improved version: Exit only the current batch, but not the caller batch

    As @dbenham mentioned, there is a new technic for exception handling that can also be used for exiting only the current batch.

    @echo off
    echo Do something, detecting some fatal error
    call :ExitBatch 3
    exit /b
    
    :ExitBatch [errorcode] - Exits only the current batch file, regardless how many CALLs
    set _errLevel=%1
    REM *** Remove all calls from the current batch from the call stack
    :popStack
    (
        (goto) 2>nul
        setlocal DisableDelayedExpansion    
        call set "caller=%%~0"
        call set _caller=%%caller:~0,1%%
        call set _caller=%%_caller::=%%
        if not defined _caller (
            REM callType = func
            rem set _errLevel=%_errLevel%
            goto :popStack
        )   
        (goto) 2>nul
        endlocal
        cmd /c "exit /b %_errLevel%"
    )
    echo NEVER REACHED
    exit /b
    

提交回复
热议问题