加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Windows – 从函数内部退出批处理脚本

发布时间:2020-12-13 20:17:51 所属栏目:Windows 来源:网络整理
导读:我的批处理文件有问题. 它通过执行以下操作自动生成几个程序: 设置一些编译标志 运行’gmake all’ 调用“检查错误级别”功能,如果errorlevel 1,退出 所以看起来像这样: set FLAG=1...gmake allcall :interactive_checkset OTHERFLAG=1...gmake allcall :i
我的批处理文件有问题.
它通过执行以下操作自动生成几个程序:

>设置一些编译标志
>运行’gmake all’
调用“检查错误级别”功能,如果errorlevel 1,退出

所以看起来像这样:

set FLAG=1
...
gmake all
call :interactive_check
set OTHERFLAG=1
...
gmake all
call :interactive_check

有6或7个(可能会增长).所以我做了一个功能来检查错误级别,而不是在每一步复制/粘贴它.
问题是这样的:错误检查是通过一个函数进行的:

: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

现在,运行它时,退出/ B 1只是退出函数,而不是批处理文件.

你知道如何退出完整的批处理文件,而无需复制/粘贴我的“if errorlevel 1 ..”在每一步?

使用致命的语法错误,如jeb所示,确实会杀死所有批处理,但它也有一个令人讨厌的副作用 – 即在保留SETLOCAL之后的环境变化,即使在批处理结束时它们应该通过隐式ENDLOCAL被丢弃.有关更多信息,请参阅我的DosTips post SETLOCAL continues after batch termination!.

根据Why does a non-interactive batch script think I’ve pressed 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

这是运行上面test.bat的示例输出.您可以看到该脚本从未退出:ExitBatch调用,并且一旦批处理终止,测试变量定义已被正确丢弃.

C:test>test.bat
test=AFTER sub SETLOCAL

C:test>set test
Environment variable test not defined

C:test>

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

重要更新:

现在可以使用纯批次来实现强大的异常处理.不仅可以抛出一个可以从任何CALL级别终止所有批处理的异常,而且还可以在更高级别捕获异常,优化特殊异常处理清理代码并恢复处理,或者继续通过另一个抛出来退出!有关更多信息,请参阅Does Windows batch support exception handling?.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读