How can I exit a batch file from within a function?

前端 未结 4 490
自闭症患者
自闭症患者 2020-12-28 08:33

I have a simple function written to check for directories:

:direxist
if not exist %~1 (
    echo %~1 could not be found, check to make sure your location is          


        
4条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-28 08:53

    jeb's solution works great. But it may not be appropriate in all circumstances. It has 2 potential drawbacks:

    1) The syntax error will halt all batch processing. So if a batch script called your script, and your script is halted with the syntax error, then control is not returned to the caller. That might be bad.

    2) Normally there is an implicit ENDLOCAL for every SETLOCAL when batch processing terminates. But the fatal syntax error terminates batch processing without the implicit ENDLOCAL! This can have nasty consequences :-( See my DosTips post SETLOCAL continues after batch termination! for more information.

    Update 2015-03-20 See https://stackoverflow.com/a/25474648/1012053 for a clean way to immediately terminate all batch processing.

    The other way to halt a batch file within a function is to use the EXIT command, which will exit the command shell entirely. But a little creative use of CMD can make it useful for solving 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've got both my version named "daveExit.bat" and jeb's version named "jebExit.bat" on my PC.

    I then test them using this batch script

    @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 potential disadvantage of the EXIT solution is that changes to the environment are not preserved. That can be partially solved by writing the environent to a temporary file before exiting, and then reading it back in.

    @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 newline character (0x0A) in the value will not be preserved properly.

提交回复
热议问题