万无一失的方法来检查非零(错误)在Windows批处理文件返回code [英] Foolproof way to check for nonzero (error) return code in windows batch file
问题描述
简介
有很多意见在那里与回报codeS在批处理文件处理(使用ERROLEVEL机制),例如
- 得到错误code文件
- ERRORLEVEL内IF
从批次中
有些建议是做如果ERRORLEVEL 1页转到somethingbad
,而另一些人建议使用%ERRORLEVEL%
变量,并使用 ==
, EQU
, LSS
等,似乎有IF 语句和这样的,所以后来delayedexpansion鼓励是在的问题,但似乎来与它自己的怪癖。
问题
什么是万无一失(即强劲,所以它几乎在任何系统上工作几乎任何回报code)的方式来知道如果一个坏的(非零)code已被回来了?
我尝试
有关基本用法,下面似乎工作确定以捕捉任何非零返回code:
如果没有ERRORLEVEL 0(
回声错误水平为非零
)
很抱歉,您尝试甚至还没有接近。 如果没有ERRORLEVEL 0
只有真,如果错误级别为负。
如果您知道ERRORLEVEL永远不会否定的,那么
如果错误级别1(回声错误级别大于0)
如果您必须允许负错误级别,而不是code的括号的块中,则
设置ERRORLEVEL = 1
设置ERRORLEVEL =
如果%ERRORLEVEL%NEQ 0(回波误差级别为非零)
的注 - 我编辑我的答案阅读乔伊的评论在这个问题链接应答之后显式地清除任何用户定义的ERRORLEVEL值。用户定义的错误级别可以掩盖我们正在试图访问动态值。但是,如果你的脚本有一个的.bat
扩展这仅适用。与的.cmd
脚本如果设置分机将设置ERRORLEVEL为0或清除变量!更糟糕的是,XP将设置ERRORLEVEL为1,如果你试图取消定义不存在的变量。这就是为什么我第一次明确地定义一个ERRORLEVEL变量的之前,我尝试将其清除!的
如果你是code的括号的块中,则必须使用延迟扩张来获取当前值
SETLOCAL enableDelayedExpansion
(
SomeCommandThatMightGenerateAnError
集ERRORLEVEL = 1
设置ERRORLEVEL =
如果!错误级别! NEQ 0(回波误差级别为非零)
)
但有时你不希望启用延迟扩展。如果你想执行一个命令后立即检查错误级别没有失去一切。
(
SomeCommandThatMightGenerateAnError&功放;&安培; (回声成功,没有错误)|| (回声有一个错误)
)
如果你绝对必须不使用扩展延迟一个括号块中,则以下工作检查动态ERRORLEVEL值。但它有两个地方的错误处理code。
(
SomeCommandThatMightGenerateAnError
如果错误级别1(回波错误级别不为零)否则,如果不ERRORLEVEL 0(回波错误级别不为零)
)
这里,终于,是终极测试非零errrolevel应该在任何情况下工作: - )
(
SomeCommandThatMightGenerateAnError
设置foundErr = 1
如果错误级别0,如果没有ERRORLEVEL 1套foundErr =
如果定义foundErr呼应错误级别为非零
)
它甚至可以被转换成一个宏为了便于使用:
设置ifErr =设置foundErr = 1及(如果错误级别0,如果没有ERRORLEVEL 1套foundErr =)及如果定义foundErr
(
SomeCommandThatMightGenerateAnError
%ifErr%回波错误级别是非零
)
宏支持括号和ELSE就好了:
%ifErr%(
回波错误级别是非零
)其他(
回声错误级别为零
)
最后一个问题:
输入和/或输出的重定向失败有任何数量的原因。但是重定向错误做的不的设置ERRORLEVEL除非 ||
运营商使用。请参阅Windows和%ERRORLEVEL% 文件重定向以获取更多信息。因此,我们可以说,不存在一个很简单的方法来检查通过错误级别的错误。最可靠的方法(但仍然不可能不犯错)是 ||
运营商。
Intro
There's a lot of advice out there for dealing with return codes in batch files (using the ERROLEVEL mechanism), e.g.
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.
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
)
Sorry, your attempt is not even close. if not errorlevel 0
is only true if errorlevel is negative.
If you know that errorlevel will never be negative, then
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!
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.
(
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:
%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 not set 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批处理文件返回code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!