Foolproof way to check for nonzero (error) return code in windows batch file

前端 未结 1 1739
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-02 13:48

Intro

There\'s a lot of advice out there for dealing with return codes in batch files (using the ERROLEVEL mechanism), e.g.

  • Get error code from withi
相关标签:
1条回答
  • 2020-12-02 14:35

    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.

    0 讨论(0)
提交回复
热议问题