如何从“调用”例程中终止 Windows 批处理文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/934030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:34:44  来源:igfitidea点击:

How to to terminate a windows batch file from within a 'call'ed routine?

windowsbatch-file

提问by Scott Langham

I've got a windows batch file, with a few sub-routines in it something like this:

我有一个 Windows 批处理文件,其中有一些子程序,如下所示:

call :a
goto :eof

:a
call :b
goto :eof

:b
:: How do I directly exit here from here?
goto :eof

I'm running this in a cmd window on Vista.
If I detect an error somewhere in the batch file, I want it to exit with a non-zero errorlevel. Is there anything I can write in the routine :b that will cause the batch file to terminate like this.

我在 Vista 的 cmd 窗口中运行它。
如果我在批处理文件中的某处检测到错误,我希望它以非零错误级别退出。有什么我可以在例程中写的:b 会导致批处理文件像这样终止。

  • I've tried 'exit', which closes the entire cmd window. That's not what I want.
  • I've tried 'exit /B 1'. That returns to the previous routine. To use this scheme after every 'call' I'd have to carefully write 'if errorlevel 1 exit /B 1' after every single 'call' to pass the error back up the call stack. I'd prefer not to have to write this line after every call.
  • 我试过“退出”,它会关闭整个 cmd 窗口。那不是我想要的。
  • 我试过“退出/B 1”。这将返回到之前的例程。要在每次“调用”后使用此方案,我必须在每次“调用”后仔细编写“if errorlevel 1 exit /B 1”以将错误返回到调用堆栈。我宁愿不必在每次通话后都写这一行。

This article was interesting, but non of the alternatives behave in the way I want. http://www.computerhope.com/exithlp.htm

这篇文章很有趣,但没有一个替代品以我想要的方式行事。http://www.computerhope.com/exithlp.htm

Is there another way?

还有其他方法吗?

Thanks.

谢谢。

回答by Joey

You can call your subroutines like so:

你可以像这样调用你的子程序:

call :b||exit /b 1

which is equivalent to

这相当于

call :b
if errorlevel 1 exit /b 1

It's slightly shorter and saves you one line, but it's still not ideal, I agree.

它稍微短了一点,为您节省了一行,但仍然不理想,我同意。

Other than that I don't see a way.

除此之外,我看不出有什么办法。

EDIT:Ok, I got a way, but it's Pure Evil?.

编辑:好的,我有办法,但它是纯粹的邪恶?。

Misusing the maximum stack size, and therefore recursion limit, we create another subroutine which simply exhausts the stack by recursively calling itself:

滥用最大堆栈大小,从而导致递归限制,我们创建了另一个子程序,它通过递归调用自身来简单地耗尽堆栈:

@echo off
echo Calling a
call :a
echo Called a
goto :eof
:a
echo Calling b
call :b
echo Called b
goto :eof
:b
echo Trying to exit
call :exit
goto :eof
:exit
call :exit

This, however, will result in the nasty error message

但是,这将导致令人讨厌的错误消息

******  B A T C H   R E C U R S I O N  exceeds STACK limits ******
Recursion Count=704, Stack Usage=90 percent
******       B A T C H   PROCESSING IS   A B O R T E D      ******

Also, it will take around 2 seconds on my machine.

此外,在我的机器上大约需要 2 秒钟。

You can suppress the error message by altering the callstatement as follows:

您可以通过call如下更改语句来抑制错误消息:

call :exit >nul 2>&1

which will redirect everything it wants to output into a great void.

这会将它想要输出的所有内容重定向到一个巨大的空白中。

But considering the time it takes to fill the stack I think the first variant would be easier.

但考虑到填充堆栈所需的时间,我认为第一个变体会更容易。

I was also contemplating using a second batch file, which, when run without callwould essentially stop the first one. But somehow that doesn't play well with subroutines. Unrolling the call stack seemingly still takes place.

我也在考虑使用第二个批处理文件,当没有运行时,它call基本上会停止第一个。但不知何故,这不适用于子程序。似乎仍然会展开调用堆栈。

回答by Jeremy E

You could create an exit.bat file that kills the the top bat file by title name.

您可以创建一个 exit.bat 文件,通过标题名称杀死顶部的 bat 文件。

Example:

例子:

A.bat

一只蝙蝠

@echo off
title A.bat
echo A.bat
call B.bat
echo A.bat

B.bat

蝙蝠

@echo off
echo B.bat
exit.bat A.bat
echo B.bat

Exit.bat

退出.bat

@echo off
echo exit.bat
kill %1