从函数内部退出批处理脚本 [英] Exit batch script from inside a function

查看:36
本文介绍了从函数内部退出批处理脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的批处理文件有问题.它通过执行以下操作自动构建多个程序:

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

  • 设置一些编译标志
  • 运行'gmake all'
  • 调用检查错误级别"函数,如果错误级别为 1,则退出

所以它看起来像这样:

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

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

There's 6 or 7 of these (and it might grow). So I made a function to check errorlevel instead of copy/pasting it at every step. The problem is this: the error checking is made through a function:

: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

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

Now, when running it, the exit /B 1 simply exits the function, but not the batch file.

你知道如何退出完整的批处理文件而不必在每一步复制/粘贴我的if errorlevel 1.."?

Do you know how to exit the complete batch file without having to copy/paste my "if errorlevel 1.." at every step?

推荐答案

使用一个致命的语法错误,正如 jeb 所展示的,确实会杀死所有的批处理,但它也有一个讨厌的副作用 - SETLOCAL 后的环境变化被保留,即使尽管它们应该在批处理结束时通过隐式 ENDLOCAL 被丢弃.有关详细信息,请参阅我的 DosTips 帖子SETLOCAL 在批处理终止后继续!.

Using a fatal syntax error, as jeb demonstrates, does kill all batch processing, but it also has a nasty side effect - environment changes after SETLOCAL are preserved, even though they are supposed to be discarded via implicit ENDLOCAL when batch processing ends. See my DosTips post SETLOCAL continues after batch termination! for more information.

根据 为什么非交互式批处理脚本认为我按下了 control-C?,我发现了一种从 CALLed 例程或脚本中退出所有批处理脚本的干净方法,并且正确丢弃 SETLOCAL 之后的所有更改.

Based on information at Why does a non-interactive batch script think I've pressed control-C?, I have discovered a clean way to exit all batch scripting from within a CALLed routine or script, and all changes after SETLOCAL are properly discarded.

@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 调用返回,并且一旦批处理终止,测试变量定义已被正确丢弃.

Here is sample output of running the above test.bat. You can see that the script never returned from the :ExitBatch call, and the test variable definition has been properly discarded once batch processing terminates.

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

C:	est>set test
Environment variable test not defined

C:	est>

:ExitBatch 例程可以放入它自己的 ExitBatch.bat 脚本中,并放置在 PATH 中的某个位置,以便任何批处理脚本都可以方便地使用它.

The :ExitBatch routine can be put into its own ExitBatch.bat script and placed somewhere within your PATH such that it can be conveniently used by any batch script.

@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 级别终止所有批处理的异常,还可以在更高级别捕获异常,执行特殊的异常处理清理代码,并继续处理,或者通过另一个抛出继续退出!有关详细信息,请参阅Windows 批处理是否支持异常处理?.

It is now possible to implement robust exception handling with pure batch. Not only can you throw an exception that can terminate all batch processing from any CALL level, but you can also catch the exception at a higher level, excecute special exception handling cleanup code, and resume processing, or continue to exit via another throw! See Does Windows batch support exception handling? for more info.

这篇关于从函数内部退出批处理脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆