Пакетные файлы Windows: .bat против .cmd?

624

Как я понимаю, .bat - это старое 16-битное соглашение об именах, а .cmd - для 32-разрядной Windows, то есть, начиная с NT. Но я по-прежнему вижу файлы .bat везде, и они, похоже, работают точно так же, используя любой суффикс. Предполагая, что моему коду никогда не понадобится работать на чем-то старше NT, действительно ли имеет значение, как я называю свои командные файлы, или есть ли gotcha, ожидающие меня, используя неправильный суффикс?

  • 17
    Просто чтобы добавить к путанице, теперь у нас также есть файлы .ps1.
  • 35
    если я не ошибаюсь .ps1 файлы должны быть Windows Power Shell. Хотя я могу ошибаться.
Показать ещё 1 комментарий
Теги:
batch-file
cmd

15 ответов

416
Лучший ответ

Из сообщения этой новостной группы самого Марка Збиковского:

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

Другими словами, если для ERRORLEVEL установлено значение, отличное от 0, а затем вы запустите одну из этих команд, в результате ERRORLEVEL будет:

  • оставить в покое с его ненулевым значением в файле .bat
  • сбросить до 0 в файле .cmd.
  • 4
    Означает ли это, что использование сценария .bat не вернет значение ERRORLEVEL 0 в случае успеха? Если это правда, я никогда этого не замечал.
  • 28
    Я думаю, это означает, что если для параметра ERRORLEVEL было установлено значение, отличное от 0, то вы запустите одну из этих команд, она останется одна (не 0) в файле .bat, но будет сброшена в 0 в файле .cmd. Но, поскольку Windows такова, как она есть, вполне возможно, что на самом деле беззвучный голос говорит вам в Pig Latin: «Сбросьте ERRORLEVEL самостоятельно, если вам так важно!».
Показать ещё 7 комментариев
374

Вот компиляция проверенной информации из различных ответов и цитируемых ссылок в этом потоке:

  • 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.
  • A script, который предназначен для 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 script (test.bat, test.cmd) находятся в одной папке, и вы запускаете script без расширения (теста), по умолчанию версия .bat из script будет работать даже в 64-битной Windows 7. Порядок выполнения контролируется переменной среды PATHEXT. См. Заказ, в котором Command Prompt выполняет файлы для более подробной информации.

Литература:

wikipedia: Сравнение командных оболочек

  • 3
    Несколько незначительных моментов: 1) .bat не обязательно вызывает command.com - по-видимому, когда вызывается command.com, это немного сложная загадка; 2) command.com был представлен с MS-DOS; 3) cmd.exe может запускать большинство сценариев command.com, но есть несколько незначительных вещей command.com, которые не работают в cmd.
  • 0
    Привет, Майк, если у тебя есть какие-то подробности о функциях command.com, которые не работают с cmd.exe, думаю, стоило бы опубликовать отдельный ответ на этот вопрос.
Показать ещё 12 комментариев
47

Эти ответы слишком длинные и ориентированы на интерактивное использование. Важные отличия для сценариев:

  • .cmd предотвращает непреднамеренное выполнение в системах, отличных от NT.
  • .cmd позволяет встроенным командам изменить уровень ошибки на 0 в случае успеха.

Расширения команд по умолчанию включены в файлах .bat и .cmd в Windows 2000 или более поздней версии.

В 2012 году и далее я рекомендую использовать исключительно .cmd.

  • 6
    ИМО, это главное. Вы используете .cmd в качестве расширения для новых сценариев, когда хотите убедиться, что они не выполняются в старых 16-разрядных ОС, или если вы не уверены, что они будут работать.
  • 3
    Я действительно ценю краткие, прагматичные и ясные ответы за тоннами стен бесполезных, похожих на университетский класс ответов.
26

Нет - это нисколько не важно. На NT расширение .bat и .cmd заставляет процессор cmd.exe обрабатывать файл точно так же.

Дополнительная интересная информация о command.com vs. 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-разрядный shell наследует все функции и средства всей Windows NT оболочки.

  • 4
    Это может иметь значение; как упоминается в тексте вашей ссылки, различия незначительны.
  • 0
    Вы можете заставить command.com выполнить команду dos, указав ее в командной строке. См. command /c ver против запуска command.com и ввода ver.
Показать ещё 2 комментария
15

RE: Очевидно, когда вызывается command.com, это немного сложная тайна;

Несколько месяцев назад, в ходе проекта, нам пришлось выяснить, почему некоторые программы, которые мы хотели запустить под CMD.EXE, на самом деле работали под командой COMMAND.COM. "Программа", о которой идет речь, была очень старым .BAT файлом, который по-прежнему работает ежедневно.

Мы обнаружили, что причина, по которой командный файл работает под COMMAND.COM, заключается в том, что он запускается из файла .PIF(также древнего). Поскольку настройки конфигурации специальной памяти, доступные только через PIF, стали неактуальными, мы заменили его обычным ярлыком на рабочем столе.

Тот же командный файл, запущенный из ярлыка, запускается в CMD.EXE. Когда вы думаете об этом, это имеет смысл. Причина, по которой нам так долго нужно было это понять, была частично связана с тем, что мы забыли, что ее элемент в группе запуска был PIF, поскольку он был в производстве с 1998 года.

  • 1
    Что это была за ОС? Что-то до XP?
13

Поскольку исходное сообщение касалось последствий использования суффикса .bat или .cmd, необязательно команды внутри файла...

Еще одно отличие между .bat и .cmd заключается в том, что если два файла существуют с тем же именем файла и обоими этими расширениями, то:

  • ввод имени файла или filename.bat в командной строке будет запущен .bat файл

  • чтобы запустить файл .cmd, вам нужно ввести filename.cmd

  • 2
    А? Если я помещаю cmd-файл в мой каталог, мне не нужно указывать расширение файла, чтобы вызвать его. Пример: echo notepad.exe% *> np.cmd Тогда, если я просто наберу "np mytextfilename.txt", он вызовет блокнот. Мне не нужно вводить «np.cmd», чтобы вызвать его.
  • 2
    @ stimpy77: Это верно, если np.cmd является единственным файлом с таким именем, но «если существуют два файла с одинаковым именем файла и обоими этими расширениями» , то единственный способ выполнить .cmd - это включить его расширение. ..
Показать ещё 2 комментария
10

Тем не менее, в 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>
  • 0
    Это происходит потому, что test.bat находится в алфавитном порядке перед test.cmd. Windows делает жадное завершение.
  • 22
    @ Дэвид: не правда. Это происходит потому, что в переменной PATHEXT расширение .BAT размещается перед .CMD (как показано в этом ответе). Если вы измените этот порядок в PATHEXT, вместо этого будет выполнен test.cmd.
Показать ещё 1 комментарий
8

все, работающие в партии, должны работать в cmd; cmd предоставляет некоторые расширения для управления средой. Кроме того, cmd выполняется в новом интерпретаторе cmd и, следовательно, должен быть быстрее (не заметно на коротких файлах) и более стабильным, поскольку bat работает под эмулируемой 16-битной средой с поддержкой NTVDM

  • 0
    Не должно иметь никакого значения в скорости. .bat не работает под DOS в NT. VDM запускается, только если программа нуждается в этом, и даже не поддерживается в 64-битной Windows, хотя я считаю, что .bat есть.
3
Выполнение файла

.cmd и .bat отличается от того, что в переменной .cmd errorlevel оно может изменяться в команде, на которую влияют расширения команд. Это действительно так.

  • 0
    Можете ли вы показать любой образец
  • 0
    Грубый ^. ^ Существуют различия в языке команд, используемых для каждого (.bat файлы получают версию совместимости). Некоторые из них могут быть проиллюстрированы этим сценарием здесь: @echo off&setlocal ENABLEEXTENSIONS call :func&&echo/I'm a cmd||echo/I'm a bat goto :EOF :func md;2>nul set var=1
Показать ещё 3 комментария
3

Слегка от темы, но вы считали Windows Scripting Host? Вам может показаться приятнее.

  • 12
    В этом отношении PowerShell, который не поддерживает WSH / cscript.exe.
  • 3
    @ stimpy77 Правда, хотя powershell мне кажется довольно ужасным.
Показать ещё 2 комментария
3

Я полагаю, что если вы измените значение переменной среды ComSpec на% SystemRoot% system32\cmd.exe, то не имеет значения, является ли расширение файла .BAT или .CMD. Я не уверен, но это может быть даже по умолчанию для WinXP и выше.

2

Расширение не имеет значения. Есть небольшие различия между COMMAND.COM обработки файла против CMD.EXE

-1

Вот одно отличие, которое я обнаружил: 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       (
...
  • 2
    Так как IF ERRORLEVEL 0 имеет значение true для любого уровня ошибки 0 или выше, он всегда должен переходить к found пути. С Windows 7 нет разницы с вашим образцом
  • 1
    @UjjwalSingh В статье службы поддержки Microsoft « Тестирование на определенный уровень ошибок в пакетных файлах» подробно описывается уровень детализации if errorlevel X который не изменяется от MS-DOS до Windows 10 независимо от пакетного файла, имеющего расширение bat или cmd . Отложенное расширение вообще не требуется для if errorlevel X синтаксиса if errorlevel X . Отложенное расширение не поддерживается MS-DOS, Windows 3.x, Windows 95 и Windows 98, но if errorlevel X поддерживается даже этими древними операционными системами.
-2

Будучи программистом Cmd и просматривая по всему Интернету, действительно не имеет значения, какой из них вы используете, вы можете иметь программу .bat на Windows 7 и запускать ее в Windows 10. но если вы должны сделать это на Windows 10, вы, вероятно, не сможете запускать все команды в Windows 7. A .cmd является точно таким же способом и запускает ту же самую программу и коды.

Все различие заключается в том, что это другое имя той же программы, если оно связано с CMD.EXE, оно выполняет те же команды.

-10

разность:

Файлы

.cmd загружаются в память перед выполнением..bat файлы выполняют строку, читают следующую строку, выполняют эту строку...

вы можете столкнуться с этим, когда вы выполните файл script, а затем отредактируете его до его выполнения. файлы bat будут испорчены этим, но cmd файлы не будут.

  • 0
    Как уже было установлено, переменная ComSpec env определяет, какая программа запускается. По сути, вы говорите, что command.com читает файл по очереди, а cmd.exe предварительно загружает файл в память? Можете ли вы привести ссылку на это?
  • 23
    Это неправильно для Vista и XP, оба типа файлов читаются построчно. Если вы приостановите файл .cmd или .bat и отредактируете его, новый код будет выполнен
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню