在 Windows 批处理文件中检查非零(错误)返回码的万无一失的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10935693/
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
Foolproof way to check for nonzero (error) return code in windows batch file
提问by Pat
Intro
介绍
There's a lot of advice out there for dealing with return codes in batch files (using the ERROLEVEL mechanism), e.g.
有很多关于处理批处理文件中的返回码的建议(使用 ERROLEVEL 机制),例如
Some of the advice is to do if errorlevel 1 goto somethingbad
, while others recommend using the
%ERRORLEVEL%
variable and using ==
, EQU
, LSS
, etc. There seem to be issues within IF
statements and such, so then delayedexpansion is encouraged, but it seems to come with quirks of its own.
一些建议是 do if errorlevel 1 goto somethingbad
,而另一些建议使用
%ERRORLEVEL%
变量并使用==
, EQU
,LSS
等。IF
语句等中似乎存在问题,因此鼓励延迟扩展,但它似乎有其自身的怪癖。
Question
题
What is a foolproof (i.e. robust, so it will work on nearly any system with nearly any return code) way to know if a bad (nonzero) code has been returned?
什么是万无一失(即健壮,因此它可以在几乎任何具有几乎任何返回代码的系统上工作)方式来知道是否返回了错误(非零)代码?
My attempt
我的尝试
For basic usage, the following seems to work ok to catch any nonzero return code:
对于基本用法,以下似乎可以捕获任何非零返回码:
if not errorlevel 0 (
echo error level was nonzero
)
回答by dbenham
Sorry, your attempt is not even close. if not errorlevel 0
is only true if errorlevel is negative.
抱歉,您的尝试还差得远。if not errorlevel 0
仅当 errorlevel 为负时才为真。
If you know that errorlevel will never be negative, then
如果你知道 errorlevel 永远不会是负数,那么
if errorlevel 1 (echo error level is greater than 0)
If you must allow for negative errorlevel, and are not within a parenthesized block of code, then
如果您必须允许负错误级别,并且不在括号内的代码块内,则
set "errorlevel=1"
set "errorlevel="
if %errorlevel% neq 0 (echo error level is non-zero)
Note - I edited my answer to explicitly clear any user defined errorlevel value after reading Joey's comment to the linked answer in the question. A user defined errorlevel can mask the dynamic value that we are trying to access. But this only works if your script has a .bat
extension. Scripts with .cmd
extension will set your ERRORLEVEL to 0 if you set or clear a variable! To make matters worse, XP will set ERRORLEVEL to 1 if you attempt to undefine a variable that does not exist. That is why I first explicitly define an ERRORLEVEL variable before I attempt to clear it!
注意 - 在阅读 Joey 对问题中链接答案的评论后,我编辑了我的答案以明确清除任何用户定义的错误级别值。用户定义的错误级别可以屏蔽我们尝试访问的动态值。但这仅在您的脚本具有.bat
扩展名时才有效。.cmd
如果您设置或清除变量,带有扩展名的脚本会将您的 ERRORLEVEL 设置为 0!更糟糕的是,如果您尝试取消定义一个不存在的变量,XP 会将 ERRORLEVEL 设置为 1。这就是为什么我在尝试清除它之前首先明确定义一个 ERRORLEVEL 变量!
If you are within a parenthesized block of code then you must use delayed expansion to get the current value
如果您在带括号的代码块中,则必须使用延迟扩展来获取当前值
setlocal enableDelayedExpansion
(
SomeCommandThatMightGenerateAnError
set "errorlevel=1"
set "errorlevel="
if !errorlevel! neq 0 (echo error level is non-zero)
)
But sometimes you don't want delayed expansion enabled. All is not lost if you want to check the error level immediately after executing a command.
但有时您不希望启用延迟扩展。如果您想在执行命令后立即检查错误级别,一切都不会丢失。
(
SomeCommandThatMightGenerateAnError && (echo Success, no error) || (echo There was an error)
)
If you absolutely must check the dynamic ERRORLEVEL value without using delayed expansion within a parenthesized block, then the following works. But it has the error handling code in two places.
如果您绝对必须检查动态 ERRORLEVEL 值而不使用带括号的块内的延迟扩展,则以下方法有效。但是它在两个地方有错误处理代码。
(
SomeCommandThatMightGenerateAnError
if errorlevel 1 (echo errorlevel is non-zero) else if not errorlevel 0 (echo errorlevel is non-zero)
)
Here, at long last, is the "ultimate" test for non-zero errrolevel that should work under any circumstances :-)
在这里,终于,是在任何情况下都应该工作的非零错误级别的“最终”测试:-)
(
SomeCommandThatMightGenerateAnError
set foundErr=1
if errorlevel 0 if not errorlevel 1 set "foundErr="
if defined foundErr echo errorlevel is non-zero
)
It can even be converted into a macro for ease of use:
为了便于使用,它甚至可以转换为宏:
set "ifErr=set foundErr=1&(if errorlevel 0 if not errorlevel 1 set foundErr=)&if defined foundErr"
(
SomeCommandThatMightGenerateAnError
%ifErr% echo errorlevel is non-zero
)
The macro supports parentheses and ELSE just fine:
宏支持括号和 ELSE 就好了:
%ifErr% (
echo errorlevel is non-zero
) else (
echo errorlevel is zero
)
One last issue:
最后一期:
Redirection of input and/or output can fail for any number of reasons. But redirection errors do notset the errorlevel unless the ||
operator is used. See File redirection in Windows and %errorlevel%for more information. So one can argue that there does not exist a fool-proof way to check for errors via errorlevel. The most reliable method (but still not infallible) is the ||
operator.
由于多种原因,输入和/或输出的重定向可能会失败。但是重定向错误不会设置错误级别,除非使用||
运算符。有关详细信息,请参阅Windows 中的文件重定向和 %errorlevel%。因此,人们可以争辩说,不存在通过错误级别检查错误的万无一失的方法。最可靠的方法(但仍然不是绝对可靠的)是||
操作符。