Gui*_*i13 18 windows function batch-file exit
我的批处理文件有问题.它通过这样的方式自动构建几个程序:
所以它看起来像这样:
set FLAG=1
...
gmake all
call :interactive_check
set OTHERFLAG=1
...
gmake all
call :interactive_check
Run Code Online (Sandbox Code Playgroud)
其中有6或7个(它可能会增长).所以我创建了一个函数来检查errorlevel而不是在每一步复制/粘贴它.问题是:错误检查是通过一个函数完成的:
:interactive_check
if errorlevel 1 (
echo.
echo /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
echo Error in compilation process... exiting
echo /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
echo.
cd %root_dir%
exit /B 1
) ELSE (
echo.Continuing to next step
)
goto:eof
Run Code Online (Sandbox Code Playgroud)
现在,在运行它时,exit /B 1只需退出函数,但不退出批处理文件.
你是否知道如何退出整个批处理文件而不必在每一步复制/粘贴我的"if errorlevel 1 .."?
jeb*_*jeb 22
有关一个好的解决方案,请参阅部件改进版
您可以在任何位置停止批处理,也可以在嵌套函数调用内部停止批处理.
您只需要创建语法错误(例如使用空块())来抑制错误消息,它可以在调用中执行,并且调用的stderr将重定向到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
Run Code Online (Sandbox Code Playgroud)
2017-04-09改进版本:仅退出当前批次,但不退出调用者批次
正如@dbenham所提到的,有一种新的异常处理技术,它也可以用于仅退出当前批处理.
@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
Run Code Online (Sandbox Code Playgroud)
dbe*_*ham 20
正如jeb演示的那样,使用致命语法错误会杀死所有批处理,但它也会产生令人讨厌的副作用 - 保留SETLOCAL后环境会发生变化,即使它们在批处理结束时应该通过隐式ENDLOCAL被丢弃.批量终止后,请参阅我的DosTips帖子SETLOCAL继续!欲获得更多信息.
基于以下信息:为什么非交互式批处理脚本认为我已按下control-C?,我发现了一种从CALLed例程或脚本中退出所有批处理脚本的简洁方法,并且正确地丢弃了SETLOCAL之后的所有更改.
@echo off
setlocal
set test=AFTER main SETLOCAL
call :sub
echo returning from main NEVER REACHED
exit /b
:sub
setlocal
set test=AFTER sub SETLOCAL
set test
call :ExitBatch
echo returning from sub2 NEVER REACHED
exit /b
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510
:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
'"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
Run Code Online (Sandbox Code Playgroud)
以下是运行上述test.bat的示例输出.您可以看到脚本从未从:ExitBatch调用返回,并且一旦批处理终止,测试变量定义已被正确丢弃.
C:\test>test.bat
test=AFTER sub SETLOCAL
C:\test>set test
Environment variable test not defined
C:\test>
Run Code Online (Sandbox Code Playgroud)
:ExitBatch例程可以放入自己的ExitBatch.bat脚本中,并放置在PATH中的某个位置,以便任何批处理脚本都可以方便地使用它.
@echo off
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510
:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
'"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
Run Code Online (Sandbox Code Playgroud)
重要更新:
现在可以使用纯批处理实现强大的异常处理.您不仅可以抛出可以从任何CALL级别终止所有批处理的异常,而且还可以在更高级别捕获异常,执行特殊异常处理清理代码,恢复处理,或继续通过另一个抛出退出!请参阅Windows批处理是否支持异常处理?了解更多信息.
当您使用exit /b X退出函数时,它会设置ERRORLEVEL为 的值X。然后,您可以使用|| 条件处理符号,如果要执行其他命令ERRORLEVEL后非零call。
@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
Run Code Online (Sandbox Code Playgroud)
这个脚本的输出是:
myfunction: Everything is good.
myfunction: got a FAIL. Will exit.
Run Code Online (Sandbox Code Playgroud)