1 (изменено: Rumata, 2018-09-20 07:40:46)

Тема: CMD/BAT: Различия между .cmd и .bat в Windows

Когда-то давно я задался вопросом "в чем разница между этими расширениями в последних версиях Windows". Делаю акцент именно на этом, потому что встречаются весьма частые ответы о том, что
-- .bat для COMMAND.COM, а .cmd для CMD.EXE
-- .bat это в Windows, а .cmd - это в OS/2

Все это далеко от ответов на поставленный вопрос. А ответ есть - https://stackoverflow.com/a/148991/3627676:

The differences between .CMD and .BAT as far as CMD.EXE is concerned are: With extensions enabled, PATH/APPEND/PROMPT/SET/ASSOC in .CMD files will set ERRORLEVEL regardless of error. .BAT sets ERRORLEVEL only on errors.

Авторский перевод

Различия между .CMD и .BAT в CMD.EXE следующие: при включенной опции ENABLEEXTENSIONS, встроенные команды PATH/APPEND/PROMPT/SET/ASSOC в .CMD файлах выставляют собственный код ошибки в ERRORLEVEL независимо от ошибки. .BAT файлы выставляют код ошибки в ERRORLEVEL только в случае ошибки.

Проиллюстрирую сказанное простым примером -- скрипт вызывает несуществующую команду (естественно, не находит ее) и печатает строку подсказки. После первой команды выставляется код ошибки 9009, который мы отображаем сразу после вызова и после встроенной команды


@echo off

non-existing-command
echo:After wrong command  : %errorlevel%

prompt
echo:After prompt command : %errorlevel%

Вывод .bat файла: команда prompt оказалась "прозрачной" для %ERRORLEVEL%


'non-existing-command' is not recognized as an internal or external command,
operable program or batch file.
After wrong command  : 9009
After prompt command : 9009

Вывод .cmd файла: здесь очевидно, что команда вернула свой код ошбки (ноль) и затерла код ошибки предыдущей команды


'non-existing-command' is not recognized as an internal or external command,
operable program or batch file.
After wrong command  : 9009
After prompt command : 0

Различия незначительные, но могут попортить нервов на поиски решения проблемы в случае скрипта, аналогичном примеру. Этот пример лишний раз говорит в пользу первичной инициализации состояния и переменных.

P.S.

Посмотрел описание команд -- туманно и рекурсивно (сепульки и сепулькарии), а про код ошибки - ни слова.

setlocal /? пишет:

. . . 
        ENABLEEXTENSIONS / DISABLEEXTENSIONS
            enable or disable command processor extensions. These
            arguments takes precedence over the CMD /E:ON or /E:OFF
            switches. See CMD /? for details.
. . .
cmd /? пишет:

. . . 
See SETLOCAL /? for details.
. . . 
To get specific details, type commandname /? to view the specifics.
prompt /? пишет:

Changes the cmd.exe command prompt.
. . . 
If Command Extensions are enabled the PROMPT command supports
the following additional formatting characters:
. . . 
( 2 * b ) || ! ( 2 * b )