Пакетные файлы Windows: .bat против.cmd?
Как я понимаю, .bat
это старое 16-битное соглашение об именах, и .cmd
для 32-битной Windows, т.е. начиная с NT. Но я продолжаю видеть файлы.bat везде, и они, кажется, работают точно так же, используя любой суффикс. Предполагая, что мой код никогда не должен будет выполняться на чем-то более старом, чем NT, действительно ли имеет значение, каким образом я называю свои командные файлы, или есть какие-то ошибки, ожидающие меня с использованием неправильного суффикса?
14 ответов
Из этой публикации в группе новостей самого Марка Збиковского:
Различия между.CMD и.BAT в том, что касается CMD.EXE, заключаются в следующем: при включенных расширениях PATH/APPEND/PROMPT/SET/ASSOC в файлах.CMD устанавливает ERRORLEVEL независимо от ошибки. .BAT устанавливает ERRORLEVEL только при ошибках.
Другими словами, если для ERRORLEVEL установлено значение, отличное от 0, а затем вы запустите одну из этих команд, в результате ERRORLEVEL будет:
- оставить в покое, отличном от 0 в файле.bat
- сбросить до 0 в файле.cmd.
Вот подборка проверенной информации из различных ответов и цитируемых ссылок в этой теме:
command.com
16-разрядный командный процессор, представленный в MS-DOS и использовавшийся в операционных системах серии Win9x.cmd.exe
32-разрядный командный процессор в Windows NT (64-разрядные ОС Windows также имеют 64-разрядную версию).cmd.exe
никогда не был частью Windows 9x. Он возник в OS/2 версии 1.0 и OS/2 версииcmd
начал 16-битный (но, тем не менее, был полноценной программой защищенного режима с такими командами, какstart
). Windows NT наследуетсяcmd
из OS/2, но версия Windows NT для Win32 началась с 32-разрядной версии. Хотя OS/2 стала 32-битной в 1992 году, ееcmd
осталась 16-битная программа OS/2 1.x.ComSpec
Переменная env определяет, какая программа запускается.bat
а также.cmd
скрипты. (Начиная с WinNT, по умолчаниюcmd.exe
.)cmd.exe
обратно совместим сcommand.com
,- Скрипт, который предназначен для
cmd.exe
можно назвать.cmd
предотвратить случайное выполнение на Windows 9x. Это расширение имени файла также восходит к OS/2 версии 1.0 и 1987.
Вот список cmd.exe
функции, которые не поддерживаются command.com
:
- Длинные имена файлов (превышающие формат 8.3)
- История команд
- Завершение вкладки
- Побег персонажа:
^
(Использовать для:\ & | > < ^
) - Стек каталогов:
PUSHD
/POPD
- Целочисленная арифметика:
SET /A i+=1
- Поиск / Заменить / подстроку:
SET %varname:expression%
- Подстановка команд:
FOR /F
(существовал ранее, был улучшен) - Функции:
CALL :label
Порядок исполнения:
Если обе версии скрипта.bat и.cmd (test.bat, test.cmd) находятся в одной папке, и вы запускаете скрипт без расширения (test), по умолчанию будет запущена версия скрипта.bat, даже на 64-битной Windows 7. Порядок выполнения контролируется переменной среды PATHEXT. См. Порядок, в котором командная строка выполняет файлы для получения дополнительной информации.
Рекомендации:
Википедия: Сравнение командных оболочек
Эти ответы слишком длинные и ориентированы на интерактивное использование. Важными отличиями являются:
.cmd
предотвращает непреднамеренное выполнение в системах, отличных от NT..cmd
позволяет встроенным командам изменить уровень ошибки на 0 в случае успеха.
Редактировать: Расширения команд по умолчанию включены в файлах.bat и.cmd в Windows 2000 или более поздней версии.
В 2012 году и далее я рекомендую использовать .cmd
исключительно.
Нет - это не имеет значения ни в малейшей степени. В NT расширение.bat и.cmd приводят к тому, что процессор cmd.exe обрабатывает файл одинаково.
Дополнительная интересная информация о command.com против cmd.exe в системах класса WinNT от MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx):
Такое поведение раскрывает довольно тонкую особенность Windows NT, которая очень важна. 16-разрядная оболочка MS-DOS (COMMAND.COM), поставляемая с Windows NT, специально разработана для Windows NT. Когда команда вводится для выполнения этой оболочкой, она фактически не выполняет ее. Вместо этого он упаковывает текст команды и отправляет его в 32-разрядную командную оболочку CMD.EXE для выполнения. Поскольку все команды фактически выполняются CMD.EXE (командная оболочка Windows NT), 16-разрядная оболочка наследует все функции и возможности полной оболочки Windows NT.
Тем не менее, в Windows 7 файлы BAT также имеют такую разницу: если вы когда-либо создадите файлы TEST.BAT и TEST.CMD в одном каталоге и запустите TEST в этом каталоге, он запустит файл BAT.
C:\>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
C:\Temp>echo echo bat > test.bat
C:\Temp>echo echo cmd > test.cmd
C:\Temp>test
C:\Temp>echo bat
bat
C:\Temp>
RE: Очевидно, когда вызывается command.com, это немного сложная загадка;
Несколько месяцев назад, в ходе проекта, мы должны были выяснить, почему некоторые программы, которые мы хотели запускать в CMD.EXE, фактически выполнялись в COMMAND.COM. "Программа", о которой идет речь, была очень старым файлом.BAT, который все еще работает ежедневно.
Мы обнаружили, что причина, по которой пакетный файл запускается в COMMAND.COM, заключается в том, что он запускается из файла.PIF (также древнего). Поскольку особые параметры конфигурации памяти, доступные только через PIF, стали неактуальными, мы заменили их обычным ярлыком на рабочем столе.
Тот же пакетный файл, запущенный из ярлыка, запускается в CMD.EXE. Когда вы думаете об этом, это имеет смысл. Причина, по которой нам потребовалось так много времени, чтобы выяснить это, частично объяснялась тем, что мы забыли, что его продукт в группе стартапов был PIF, потому что он был в производстве с 1998 года.
Так как исходный пост касался последствий использования суффикса.bat или.cmd, необязательно команды внутри файла...
Еще одно отличие между.bat и.cmd состоит в том, что если существуют два файла с одинаковым именем и обоими расширениями, то:
ввод имени файла или имени файла.bat в командной строке запустит файл.bat
чтобы запустить файл.cmd, вы должны ввести имя файла.cmd
Все, что работает в пакете, должно работать в cmd; cmd предоставляет некоторые расширения для управления средой. Кроме того, cmd выполняется в новом интерпретаторе cmd и, следовательно, должен быть быстрее (незаметно для коротких файлов) и более стабильным, поскольку bat работает в эмулируемой 16-битной среде NTVDM.
Выполнение файлов.cmd и.bat отличается, потому что в переменной.cmd errorlevel он может меняться в команде, на которую влияют расширения команд. Это действительно так.
Немного не по теме, но рассматривали ли вы Windows Scripting Host? Вы можете найти это лучше.
Я считаю, что если вы измените значение переменной среды ComSpec на%SystemRoot%system32\cmd.exe, тогда не имеет значения, является ли расширение файла.BAT или.CMD. Я не уверен, но это может быть даже по умолчанию для WinXP и выше.
Расширение не имеет значения. Есть небольшие различия между COMMAND.COM, обрабатывающим файл, и CMD.EXE
Вот одно отличие, которое я обнаружил: EnableDelayedExpansion
требуется в .cmd
файлы.
Где как в случае .bat
файлы неявно по умолчанию. (Windows 10)
dir *? | find /i "FOOBAR"
if ERRORLEVEL 0 (
set result="found" ) else (
set result="not found" )
echo %result%
Это работает в .bat
но всегда found
в случае .cmd
файл.
изменения line 2
на следующее заставляет это работать как ожидалось:
if %ERRORLEVEL% equ 0 (
И, наконец, для .cmd
файл это работает правильно:
setLocal EnableDelayedExpansion
...
if !ErrorLevel! equ 1 (
...
Будучи программистом Cmd и просматривая весь Интернет, на самом деле не имеет значения, какой вы используете, вы можете иметь .bat
запрограммируйте на Windows 7 и запустите его на Windows 10. но если вы хотите сделать это на Windows 10, вы, вероятно, не сможете выполнить все команды на Windows 7. A .cmd
точно так же, и запускает точно такую же программу и коды.
Разница лишь в том, что это другое имя одной и той же программы, если она подключена к CMD.EXE
, он запускает те же команды.
Разница:
Файлы.cmd загружаются в память перед выполнением. Файлы.bat выполняют строку, читают следующую строку, выполняют эту строку...
вы можете столкнуться с этим, когда вы выполняете файл сценария, а затем редактируете его, прежде чем он завершится. Файлы bat будут испорчены этим, а файлы cmd - нет.