如何从“调用”例程中终止 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 call
statement 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 call
would 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