如何从子程序内部退出批处理文件?
如果我使用 EXIT 命令,我只需返回到调用子程序的行,然后继续执行。
以下是一个例子:
@echo off
ECHO Quitting...
CALL :QUIT
ECHO Still here!
GOTO END
:QUIT
EXIT /B 1
:END
EXIT /B 0
输出:
Quitting...
Still here!
更新:
这不是一个正确的答案,但我最终做了类似的事情:
@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
双管语句:
CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL
是以下的简写:
CALL :SUBROUTINE_WITH_ERROR
IF ERRORLEVEL 1 GOTO HANDLE_FAIL
我仍然很想知道是否有办法直接退出子程序,而不必让 CALLER 处理这种情况,但这至少可以完成工作。
更新#2:当从另一个子程序中调用一个子程序时,以上述方式调用,我从子程序内部调用如下:
CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1
这样,错误就会传播回“主”部分。然后,批处理的主要部分可以使用错误处理程序 GOTO :FAILURE 来处理错误
答案1
将其添加到批处理文件的顶部:
@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
)
然后你只需调用:
EXIT [errorLevel]
如果你想退出整个文件EXIT /B [errorLevel]
退出当前子程序GOTO :EOF
退出当前子程序
答案2
这个小调整怎么样?
@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
输出:
Quitting...
从技术上来说,这并不是从子程序中退出。相反,它只是检查子程序的结果并从那里采取行动。
答案3
这将退出当前上下文和父上下文(即,当在一个call
深层子程序脚本内执行时将退出):
(goto) 2>nul || exit /b
或者,如果您需要错误级别 0:
(goto) 2>nul || (
type nul>nul
exit /b
)
基本上,(goto) 2>nul
将错误级别设置为 1(不输出错误),将执行返回到父上下文,并在父上下文中执行双管道后的代码。type nul>nul
将错误级别设置为 0。
更新:
要连续两次返回执行,(goto) 2>nul ||
请像这样链接几次:
(goto) 2>nul || (goto) 2>nul || (goto) 2>nul || (
type nul>nul
exit /b
)
这是一个递归子程序,用于返回不同次数的上下文:
:Kill
(goto) 2>nul || (
set /a depth=%1-1
if %1 GEQ 1 (
call:Kill !depth!
)
(goto) 2>nul || (type nul>nul)
)
从递归函数调用时:
@echo off
setlocal EnableDelayedExpansion
call:Recurs 5
echo This won't be printed
exit /b
:Recurs
set /a ri+=1
echo %ri%
if %ri% LSS %1 (
call:Recurs %1
)
echo This will be printed only once
call:Kill %1
exit /b
输出将是:
1
2
3
4
5
This will be printed only once
答案4
我将错误处理放在批处理文件中。您可以像这样调用错误处理程序:
CALL :WARNING "This is" "an important" "warning."
以下是该批处理文件的结尾:
::-------------------------------------------------------------------
:: 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)