在批处理文件中使用返回代码(使用ERROLEVEL机制)有很多建议,例如。
> Get error code from within a batch file
> ERRORLEVEL inside IF
一些建议是做,如果错误级别1 goto somethingbad,而其他人推荐使用
%ERRORLEVEL%变量和使用==,EQU,LSS等。在IF语句中似乎存在问题等等,因此鼓励延迟扩展,但似乎有自己的怪癖。
题
什么是愚蠢的(即稳健的,所以它几乎可以用几乎任何返回代码的任何系统都可以使用)来知道是否返回了一个坏的(非零)代码?
我的尝试
为了基本使用,以下似乎可以正常工作来捕获任何非零返回码:
if not errorlevel 0 ( echo error level was nonzero )
如果你知道错误级别永远不会是负数,那么
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的评论后,链接的答案在问题。用户定义的错误级别可以屏蔽我们尝试访问的动态值。但是,如果您的脚本具有.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 )
最后一个问题:
输入和/或输出的重定向可能由于任何原因而失败。但重定向错误不设置错误级别,除非||运算符被使用。有关详细信息,请参阅File redirection in Windows and %errorlevel%。所以人们可以认为,不存在通过错误级别检查错误的傻瓜方式。最可靠的方法(但仍然不可靠)是||操作符。