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 successfully, 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 positive, non-zero return code.
IF NOT ERRORLEVEL 0 ... will return TRUE for every negative, non-zero return code.
|In CMD.EXE (Windows NT 4 and later) the old-fashioned DOS
However, this can be fixed by using the following code to check for non-zero return codes:
Use the code above wherever you would have used
Thanks for Noe Parenteau for this tip.
In COMMAND.COM (MS-DOS, DOS-box, Windows 9*/ME), 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:
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:
This will result in many more lines of batch code, but at least it will work in any DOS version.
In Windows NT (Windows NT 4 ... Windows 10) this may not suffice, though, because errorlevels can have negative integer values as well.
In DOS (COMMAND.COM), 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%
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.
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:
where number can be any number from 0 to 255.
A small Kix "one liner" can be used too:
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
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.
In NT 4 use either
VERIFY OTHER 2> NUL
to set an errorlevel 1.
In Windows 2000 and later the
EXIT command accepts an optional exit code, a.k.a. return code or errorlevel, e.g.
EXIT /B 1 for errorlevel 1:
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 ]
If you want to set an errorlevel inside a batch file, for example to test an external command used by that batch file, you can use
CMD.EXE /K EXIT 6 to set errorlevel 6 and continue.
Do NOT use
SET ErrorLevel=6 as this will render the
Errorlevel variable static.
• 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 modified: 2022-04-01