Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?
This answer is based on experiments I ran under Windows 10. I doubt there are differences with earlier Windows versions that use cmd.exe, but it is possible.
Also note - This answer does not attempt to document the ERRORLEVEL result when an internal command encounters an error (except for a wee bit concerning DEL and ERASE)
Not only are there difference between commands, but a single command can behave differently depending on whether it was run from the command line, or within a batch script with a .bat
extension, or from within a batch script with a .cmd
extension.
The following set of commands never clear the ERRORLEVEL to 0 upon success, regardless of context, but instead preserve the prior ERRORLEVEL:
- BREAK
- CLS
- ECHO
- ENDLOCAL
- FOR : Obviously, commands in the DO clause may set the ERRORLEVEL, but a successful FOR with at least one iteration does not set the ERRORLEVEL to 0 on its own.
- GOTO
- IF : Obviously, commands executed by IF may set the ERRORLEVEL, but a successful IF does not set ERRORLEVEL to 0 on its own.
- KEYS
- PAUSE
- POPD
- RD
- REM
- RMDIR
- SHIFT
- START
- TITLE
The next set of commands always clear the ERRORLEVEL to 0 upon success, regardless of context:
- CD
- CHDIR
- COLOR
- COPY
- DATE
- DEL : Always clears ERRORLEVEL, even if the DEL fails (except when run without any file argument).
- DIR
- ERASE : Always clears ERRORLEVEL, even if ERASE fails. (except when run without any file argument).
- MD
- MKDIR
- MKLINK
- MOVE
- PUSHD
- REN
- RENAME
- SETLOCAL
- TIME
- TYPE
- VER
- VERIFY
- VOL
Then there are these commands that do not clear ERRORLEVEL upon success if issued from the command line or within a script with a .bat
extension, but do clear the ERRORLEVEL to 0 if issued from a script with a .cmd
extension. See https://stackoverflow.com/a/148991/1012053 and https://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.admin/XHeUq8oe2wk/LIEViGNmkK0J for more info.
- ASSOC
- DPATH
- FTYPE
- PATH
- PROMPT
- SET
Lastly, there are these commands that do not fit neatly into any of the prior categories:
CALL : If a :routine or batch script is CALLed, then ERRORLEVEL is exclusively controlled by the CALLed script or :routine. But any other type of successful CALL to a command will always clear ERRORLEVEL to 0 if the CALLed command does not otherwise set it.
Example:call echo OK
.EXIT : If used without
/B
, then the cmd.exe session terminates and there is no more ERRORLEVEL, just the cmd.exe return code. ObviouslyEXIT /B 0
clears the ERRORLEVEL to 0, butEXIT /B
without a value preserves the prior ERRORLEVEL.
I believe that accounts for all internal commands, unless there is an undocumented command that I missed.
Your description of CALL
command is incomplete:
CALL : Clears ERRORLEVEL if the CALLed command does not otherwise set it. Example:
call echo OK
.
Check this small example:
@echo off
call :setTwo
echo Set two: %errorlevel%
call :preserve
echo Preserve: %errorlevel%
call echo Reset
echo Reset: %errorlevel%
call :subNotExists 2> NUL
echo Sub not exist: %errorlevel%
goto :EOF
:setTwo
exit /B 2
:preserve
echo Preserve
exit /B
Output:
Set two: 2
Preserve
Preserve: 2
Reset
Reset: 0
Sub not exist: 1
CALL
description should say something like this:
- CALL : Clears ERRORLEVEL if the CALLed command does not otherwise set it. Example:
call echo OK
, but if the called command is a subroutine it preserves the prior ERRORLEVEL. If the called subroutine does not exist, it sets the ERRORLEVEL to 1.