Errorlevels

The correct name for errorlevels would be return codes.
But since the DOS command to determine the return code is IF ERRORLEVEL, most people use the name errorlevel.

Errorlevels are not a standard feature of every command.
A certain errorlevel may mean anything the programmer wanted it to.
Most programmers agree that an errorlevel 0 means the command executed succesfully, and an errorlevel 1 or higher usually spells trouble.
But there are many exceptions to this general rule.

IF ERRORLEVEL construction has one strange feature, that can be used to our advantage: it returns TRUE if the return code was equal to or higher than the specified errorlevel.

This means most of the time we only need to check IF ERRORLEVEL 1 ... and this will return TRUE for every non-zero return code.

In Windows NT 4/2000/XP this may sometimes fail, since some executables return negative numbers for errorlevels!
However, this can be fixed by using the following code to check for non-zero return codes:

IF %ERRORLEVEL% NEQ 0 ...
Use the code above wherever you would have used IF ERRORLEVEL 1 ... in the "past".

Thanks for Noe Parenteau for this tip.

To determine the exact return code the previous command returned, we could use a construction like this:

@ECHO OFF
IF ERRORLEVEL 1 SET ERRORLEV=1
IF ERRORLEVEL 2 SET ERRORLEV=2
IF ERRORLEVEL 3 SET ERRORLEV=3
IF ERRORLEVEL 4 SET ERRORLEV=4
   •
   •
   •
IF ERRORLEVEL 254 SET ERRORLEV=254
IF ERRORLEVEL 255 SET ERRORLEV=255
ECHO ERRORLEVEL = %ERRORLEV%

This is perfectly OK if we only have to check, say, 15 consecutive errorlevels.
If we need to check every errorlevel, though, there are better alternatives.

In Windows NT 4 (and 2000?) this won't work, since the SET command itself will set an errorlevel (usually 0)!
(As I learned from Charles Long, in XP the SET command no longer sets an errorlevel itself.)
However, Windows NT 4 and later make it easy by storing the latest errorlevel in the environment variable ERRORLEVEL:

ECHO.%ERRORLEVEL%
will display the errorlevel.

This blog entry by Batcheero explains perfectly why you should never SET the ERRORLEVEL variable.

The safest way to use errorlevels for
all DOS versions is the reverse order check.
Start checking the highest errorlevel that can be expected, then check for the one below, etcetera:

IF ERRORLEVEL 255 GOTO Label255
IF ERRORLEVEL 254 GOTO Label254
  •
  •
  •
IF ERRORLEVEL   2 GOTO Label2
IF ERRORLEVEL   1 GOTO Label1
GOTO Label0

:Label255
(commands to be executed at errorlevel 255)
GOTO End

  •
  •
  •

:Label1
(commands to be executed at errorlevel 1)
GOTO End

:Label0
(commands to be executed at errorlevel 0, or no errorlevel)

:End


This will result in many more lines of batch code, but at least it will work in any DOS version.

In DOS for the rest of us, we can use FOR loops to determine the errorlevel:

@ECHO OFF
REM Reset variables
FOR %%A IN (1 10 100) DO SET ERR%%A=

REM Check error level hundredfolds
FOR %%A IN (0 1 2) DO IF ERRORLEVEL %%A00 SET ERR100=%%A
IF %ERR100%==2 GOTO 200
IF %ERR100%==0 IF NOT "%1"=="/0" SET ERR100=

REM Check error level tenfolds
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL %ERR100%%%A0 SET ERR10=%%A
IF "%ERR100%"=="" IF %ERR10%==0 SET ERR10=

:1
REM Check error level units
FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
REM Modification necessary for errorlevels 250+
IF NOT ERRORLEVEL 250 FOR %%A IN (6 7 8 9) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
GOTO End

:200
REM In case of error levels over 200 both
REM tenfolds and units are limited to 5
REM since the highest DOS error level is 255
FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 2%%A0 SET ERR10=%%A
IF ERR10==5 FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 25%%A SET ERR1=%%A
IF NOT ERR10==5 GOTO 1

:End
REM Clean up the mess and show results
SET ERRORLEV=%ERR100%%ERR10%%ERR1%
FOR %%A IN (1 10 100) DO SET ERR%%A=
ECHO ERRORLEVEL  %ERRORLEV%
Click to view source
Click to download source

This example still handles only 255 error levels (that's all there is in DOS), but it can be easily adjusted once you understand the basic principles.

To check errorlevels during batch file development, use either COMMAND /Z yourbatch.bat to display the errorlevel of every command executed in MS-DOS 7.* (Windows 95/98), or PROMPT Errorlevel$Q$R$_$P$G in OS/2 Warp (DOS) sessions.

 

Setting errorlevels

MS-DOS & Windows 9x:

Use ERRORLVL.EXE from OzWoz Software, or SETERLEV.COM 1.0 from Jim Elliott to test batch files that (are supposed to) check on errorlevels.
The syntax couldn't be simpler:

ERRORLVL number

or

SETERLEV number

where number can be any number from 0 to 255.

A small Kix "one liner" can be used too:

EXIT $ErrLev

If called by a batch like this:

KIX32 ERRORLEVEL.KIX $ErrLev=23

it will return an errorlevel 23 (ERRORLEVEL.KIX would be the name of the kix script mentioned above).

Or use CHOICE.COM, available in all DOS 6.* and up versions, to set an errorlevel:

ECHO 5 | CHOICE /C:1234567890 /N

and

ECHO E | CHOICE /C:ABCDEFGHIJ /N

will both result in errorlevel 5 since both 5 and E are the fifth choice (/C:...) in the corresponding CHOICE commands.

 

Windows NT 4 and later:

In NT 4 use either

COLOR 00

or

VERIFY OTHER 2> NUL

to set an errorlevel 1.

 

Windows 2000 and later:

In Windows 2000 & XP a new /B switch has been added to the EXIT command, enabling the batch file to quit with a return code:

EXIT

Quits the CMD.EXE program (command interpreter) or the current batch script.

EXIT  [ /B ]  [ exitCode ]

/B Specifies to exit the current batch script instead of CMD.EXE.
If executed from outside a batch script, it will quit CMD.EXE.
 
exitCode Specifies a numeric number.
If /B is specified, sets ERRORLEVEL that number.
If quitting CMD.EXE, sets the process exit code with that number.
 

Brought to my attention by Maor Conforti. Thanks ]

 

Related stuff

• Use EXIT in Windows 2000 (and later) to set errorlevels.

• See how errorlevels are used to check the availability of third party tools, and how your batch file can even help the user download the tool if it isn't available.

• This blog entry by Batcheero explains perfectly why you should never SET the ERRORLEVEL variable.
The same goes for other dynamic environment variables like CD (current directory), DATE (current date), TIME (current time), RANDOM (random decimal number between 0 and 32767), CMDEXTVERSION (current Command Processor Extensions version) and CMDCMDLINE (the original command line that invoked the Command Processor).

 

 


page last uploaded: 20 November 2013, 11:51
Fileaze