如何从“调用”例程中终止 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
How to to terminate a windows batch file from within a 'call'ed routine?
提问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

