Какой cmd.внутренние команды exe очищают уровень ошибок до 0 после успеха?

частым методом обработки ошибок в пакетных сценариях Windows является использование таких вещей, как
if errorlevel 1 ... или if %errorlevel% neq 0 .... Часто требуется, чтобы код обработки ошибок сохранял уровень ошибок.

Я считаю, что все внешние команды всегда приведут к тому, что ERRORLEVEL будет установлен в некоторое значение, поэтому код обработки ошибок должен сохранить ERRORLEVEL в переменной среды перед выполнением внешней команды.

но как насчет внутренних команд? Проблема есть, некоторые внутренние команды очищают ERRORLEVEL до 0, когда они преуспевают, а некоторые нет. И я не могу найти никакой документации, указывающей, какие команды делают что.

Итак, вопрос в том,какие внутренние команды очищают уровень ошибок до 0 после успеха? это не общий вопрос о возвращенных кодах ERRORLEVEL, но строго о результатах успеха.

есть сообщения, такие как каков самый простой способ сброса Errorlevel на ноль? и пакетные файлы Windows: .bat vs .cmd? которые дают частичные ответы. Но я никогда не видел полного списка.

Примечание: мне было любопытно об этом в течение многих лет. Поэтому я, наконец, решил провести кучу экспериментов и придумать окончательный ответ. Я публикую этот Q&A, чтобы поделиться тем, что я нашел.

2 ответов


этот ответ основан на экспериментах, которые я запускал под Windows 10. Я сомневаюсь, что есть различия с более ранними версиями Windows, что использование cmd.exe, но это возможно.

Также обратите внимание - этот ответ не пытается документировать результат ERRORLEVEL, когда внутренняя команда обнаруживает ошибку (за исключением небольшого бита, касающегося DEL и ERASE)

не только есть разница между командами, но одна команда может вести себя по-разному в зависимости от того, был запущен из командной строки или пакетного сценария с .bat расширение или из пакетного скрипта с


описание CALL команда не завершена:

CALL: очищает ERRORLEVEL, если вызываемая команда не устанавливает его иначе. Пример: call echo OK.

проверьте этот небольшой пример:

@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

выход:

Set two: 2
Preserve
Preserve: 2
Reset
Reset: 0
Sub not exist: 1

CALL описание должно сказать что-то вроде этого:

  • CALL: очищает ERRORLEVEL, если вызываемая команда не устанавливает его иначе. Пример: call echo OK, но если назвать команда-это подпрограмма, которая сохраняет предыдущий уровень ошибок. Если вызываемая подпрограмма не существует, она устанавливает ERRORLEVEL в 1.