Errorlevel and Exit codes

Almost all applications and utilities will set an Exit Code when they complete/terminate.

The exit codes that are set do vary, in general a code of 0 (false) will indicate successful completion.

The exit codes set by resource kit utilities are not always consistent, they can vary between machines with different Service packs/Resource kit updates applied. Some utilities will return negative numbers as an exit code.

If you attempt to execute a non-existent command %ERRORLEVEL% will be set to 9009

Detecting Errorlevels

There are two different methods of checking an errorlevel, the first syntax provides compatibility with old .bat batch files from the era of MS-DOS

The errorlevel is made available via IF ERRORLEVEL ... or the %ERRORLEVEL% variable.

IF ERRORLEVEL n statements should be read as IF Errorlevel >= number
i.e.
IF ERRORLEVEL 0 will return TRUE whether the errorlevel is 0, 1 or 5 or 64
IF ERRORLEVEL 1 will return TRUE whether the errorlevel is 1 or 5 or 64
IF NOT ERRORLEVEL 3 means if ERRORLEVEL is less than 3 ( 2, 1, 0 or a negative number).

To check for a specific error level N, you can use the following construct:

IF ERRORLEVEL N IF NOT ERRORLEVEL N+1 COMMAND

This is not very readable or user friendly and does not account for negative error numbers.

A preferred method of checking Errorlevels is to use the %ERRORLEVEL% variable:

IF %ERRORLEVEL% NEQ 0 Echo An error was found
IF %ERRORLEVEL% EQU 0 Echo No error found

IF %ERRORLEVEL% EQU 0 (Echo No error found) ELSE (Echo An error was found)
IF %ERRORLEVEL% EQU 0 Echo No error found || Echo An error was found

This allows you to trap errors that can be negative numbers, you can also test for specific errors:
IF %ERRORLEVEL% EQU 64 ...

When ending a subroutine, you can use EXIT /b N to set a specific ERRORLEVEL N.

You should never attempt to SET the %ERRORLEVEL% because that will create a user variable named %ERRORLEVEL% which then takes precedence over the internal pseudo variable %ERRORLEVEL%.

Raymond Chen [MSFT] explains: ERRORLEVEL is not the same as the %ERRORLEVEL% environment variable.

Error level vs Exit code

When an external command is run by CMD.EXE, it will detect the executable's Return or Exit Code and set the ERRORLEVEL to match. In most cases the ERRORLEVEL will be the same as the Exit code, but there are some cases where they can differ.

An Exit Code can be detected directly with redirection operators (Success/Failure ignoring the ERRORLEVEL) this can often be more reliable than trusting the ERRORLEVEL which may or may not have been set correctly.

Old style .bat Batch files vs .cmd Batch scripts.

There is a key difference between the way .CMD and .BAT batch files set errorlevels:

A .BAT batch script running the 'new' internal commands: APPEND, ASSOC, PATH, PROMPT, FTYPE and SET will only set ERRORLEVEL if an error occurs. So if you have two commands in the batch script and the first fails, the ERRORLEVEL will remain set even after the second command succeeds.

This can make debugging a problem .BAT script more difficult, a .CMD batch script is more consistent and will set ERRORLEVEL after every command that you run [source] Mark Zbikowski (MSFT).

Heres a simplified example script with an error check after each command:

command1
if %errorlevel% EQU 0 (echo OK ) Else ( Echo ERROR FAILED &color CF )
command2
if %errorlevel% EQU 0 (echo OK ) Else ( Echo ERROR FAILED &color CF )

A .CMD batch file running the above will display an error after the command that fails.
A .BAT batch file running the above will display an error after the command that fails and also for every subsequent test.

Even in the CMD shell, some commands don't follow the rules

Even though a CMD batch script should set or reset ERRORLEVEL after every command, there are a few exceptions:

Commands that do NOT affect the ERRORLEVEL:
BREAK, ECHO, ENDLOCAL, FOR, IF, PAUSE, REM, RD/RMDIR, TITLE

Commands that will set but not clear an ERRORLEVEL:
CLS, GOTO, KEYS, POPD, SHIFT

Commands that set an Exit Code but not the ERRORLEVEL:
RD/RMDIR

Commands that set an ERRORLEVEL but not the Exit Code (SO explanation):
MD/MKDIR

There is some possible logic to this

Force an exit code

You can make a batch file return a non-zero exit code by using the EXIT command.

Exit 0
Exit /B 5

To force an ERRORLEVEL of 1 to be set without exiting, run a small but invalid command like COLOR 00

PowerShell

In PowerShell $? contains True if last operation succeeded and False otherwise.

The exit code of the last Win32 executable execution is stored in the automatic variable $LASTEXITCODE

To read exit codes (other than 0 or 1) launch the PowerShell script and return the $LASTEXITCODE in a single line like this:

powershell.exe -noprofile C:\scripts\script.ps1; exit $LASTEXITCODE

“I’d rather wake up in the middle of nowhere than in any city on earth” ~ Steve McQueen

Related:

Robocopy exit codes
Conditional Execution - if command1 succeeds then execute command2
List of ERRORLEVEL values set by internal cmd.exe commands - Stackoverflow /Aacini
ERRORLEVEL is not %ERRORLEVEL% - The old new thing blog


 
Copyright © SS64.com 1999-2019
Some rights reserved