万无一失的方法来检查Windowsbatch file中的非零(错误)返回码

介绍

在这里有很多的build议来处理batch file中的返回码(使用ERROLEVEL机制),例如

  • 从batch file中获取错误代码
  • IF中的ERRORLEVEL

其中一些build议是, if errorlevel 1 goto somethingbad ,其他人则build议使用%ERRORLEVEL%variables,并使用==EQULSS等。IF语句中似乎存在一些问题,所以鼓励delayedexpansion,但它似乎有自己的怪癖。

什么是一个万无一失的(即健壮的,所以它几乎可以在几乎任何返回代码的系统上工作)的方式来知道一个坏的( 非零 )代码是否已经被返回?

我的企图

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

 if not errorlevel 0 ( echo error level was nonzero ) 

对不起,你的尝试不是很接近。 if not errorlevel 0则只有在错误级别为负数时才为真。

如果你知道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) 

注 – 我编辑了我的答案,明确清除任何用户定义的错误级别值后,阅读乔伊的问题链接的答案。 用户定义的错误级别可以掩盖我们尝试访问的动态值。 但是这只有在脚本的扩展名是.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) ) 

在这里,最后是在任何情况下都可以工作的非零errrolevel的“终极”测试:-)

 ( 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 ) 

最后一个问题:

输入和/或输出的重定向可能由于许多原因而失败。 但重定向错误不会设置错误级别,除非|| 运算符被使用。 有关更多信息,请参阅Windows中的文件重定向和%errorlevel% 。 所以人们可以争辩说,不存在一个通过错误级别检查错误的傻瓜式的方法。 最可靠的方法(但仍然不可靠)是|| 运营商。