在Windows批处理文件中检查非零(错误)返回代码的万无一失的方法

时间:2012-06-07 16:13:10

标签: windows batch-file

简介

有许多建议用于处理批处理文件中的返回代码(使用ERROLEVEL机制),例如

一些建议是if errorlevel 1 goto somethingbad,而其他建议使用。{1}} %ERRORLEVEL%变量并使用==EQULSS等。IF语句中似乎存在问题等等,因此鼓励delayedexpansion,但它似乎带有自己的怪癖。

问题

什么是万无一失(即强大的,所以它几乎可以在几乎所有返回代码的系统上运行),以了解是否返回了错误的(非零)代码?

我的尝试

对于基本用法,以下似乎可以正常捕获任何非零返回码:

if not errorlevel 0 (
    echo error level was nonzero
)

1 个答案:

答案 0 :(得分:40)

对不起,您的尝试甚至没有结束。 if not errorlevel 0仅在errorlevel为负数时才为真。

如果您知道errorlevel永远不会消极,那么

if errorlevel 1 (echo error level is greater than 0)

如果你必须允许负的错误级别,并且不在带括号的代码块内,那么

set "errorlevel=1"
set "errorlevel="
if %errorlevel% neq 0 (echo error level is non-zero)

注意 - 在阅读Joey对问题中链接答案的评论后,我编辑了我的答案以明确清除任何用户定义的errorlevel值。用户定义的errorlevel可以屏蔽我们尝试访问的动态值。但这仅适用于您的脚本具有.bat扩展名的情况。如果您设置或清除变量,带有.cmd扩展名的脚本会将您的ERRORLEVEL设置为0!更糟糕的是,如果您尝试取消定义不存在的变量,XP会将ERRORLEVEL设置为1。这就是我在尝试清除它之前首先明确定义ERRORLEVEL变量的原因!

如果您在带括号的代码块中,则必须使用延迟扩展来获取当前值

setlocal enableDelayedExpansion
(
  SomeCommandThatMightGenerateAnError
  set "errorlevel=1"
  set "errorlevel="
  if !errorlevel! neq 0 (echo error level is non-zero)
)

但有时您不希望启用延迟扩展。如果要在执行命令后立即检查错误级别,则不会丢失所有内容。

(
  SomeCommandThatMightGenerateAnError && (echo Success, no error) || (echo There was an error)
)

如果绝对必须检查动态ERRORLEVEL值而不使用带括号的块中的延迟扩展,则以下方法有效。但它在两个地方都有错误处理代码。

(
  SomeCommandThatMightGenerateAnError
  if errorlevel 1 (echo errorlevel is non-zero) else if not errorlevel 0 (echo errorlevel is non-zero)
)


在这里,最后,对于非零错误级别的“终极”测试应该在任何情况下都有效: - )

(
  SomeCommandThatMightGenerateAnError
  set foundErr=1
  if errorlevel 0 if not errorlevel 1 set "foundErr="
  if defined foundErr echo errorlevel is non-zero
)

它甚至可以转换为宏以便于使用:

set "ifErr=set foundErr=1&(if errorlevel 0 if not errorlevel 1 set foundErr=)&if defined foundErr"
(
  SomeCommandThatMightGenerateAnError
  %ifErr% echo errorlevel is non-zero
)

宏支持括号和ELSE就好了:

%ifErr% (
  echo errorlevel is non-zero
) else (
  echo errorlevel is zero
)


最后一期:

输入和/或输出的重定向可能由于多种原因而失败。但是,除非使用||运算符,否则重定向错误设置errorlevel。有关详细信息,请参阅File redirection in Windows and %errorlevel%。因此,人们可以争辩说,不存在通过错误级别检查错误的万无一失的方法。最可靠的方法(但仍然不可靠)是||运算符。