Пакетні файли Windows: .bat vs .cmd?


747

Як я розумію, .batце стара 16-бітна конвенція іменування, і .cmdвона призначена для 32-розрядних Windows, тобто починаючи з NT. Але я продовжую бачити файли .bat скрізь, і вони, здається, працюють точно так само, використовуючи будь-який суфікс. Якщо припустити, що мій код ніколи не потрібно працювати на чомусь старшому, ніж NT, чи дійсно має значення, яким способом я називаю свої пакетні файли, чи є якась чекання на мене, використовуючи неправильний суфікс?


19
Просто для додання плутанини у нас також є .ps1 файли.
Мартін Браун

42
якщо я не помиляюся. Файли .ps1 повинні бути файлом Windows Power Shell. Я можу помилитися.
CMS_95

Відповіді:


454

З цієї групи новин проводки по Mark Zbikowski сам:

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

Іншими словами, якщо для ERRORLEVEL встановлено значення не-0 і ви запустили одну з цих команд, результатом ERRORLEVEL буде:

  • залишено в спокої за значенням, яке не становить 0, у файлі .bat
  • скинути до 0 у файлі .cmd.

4
Чи означає це, що використання сценарію .bat не поверне значення ERRORLEVEL 0 на успіх? Якщо це правда, я цього ніколи не помічав.
djangofan

31
Я думаю, це означає, що якщо ERRORLEVEL був встановлений на не-0, то ви запустите одну з цих команд, вона залишиться в самому (non-0) у .bat файлі, але скинеться до 0 у .cmd-файлі. Але, оскільки Windows є такою, якою вона є, цілком можливо, що насправді викликає зневірений голос, щоб сказати тобі на Свинському латині: "Скиньте ERRORLEVEL себе, якщо ви так турбуєтесь!".
MadScientist

5
Я думаю, що це означає, що тільки ті конкретні команди виконували б різні дії "set / not set". Інші працюватимуть як нормально
PsychoData

1
Я тепер розумію. Я оновив свою суть. Мабуть, вона не (повторно) встановлює рівень помилок при виклику set var=..оператора. Що дивно, тому що я припускав, що така очікувана поведінка. Аргументи можна зробити для обох. Я буду дотримуватися файлів .bat. :-)
wasatchwizard

1
Примітка. Команда APPEND була замінена на незадокументовану команду DPATH, хоча команду DPATH /?досі перелічено як APPEND. Крім того, стаття Wiki з тих пір в основному виправлена, за винятком того, що вона не перераховує DPATH.
dbenham

417

Ось збірка перевіреної інформації з різних відповідей та цитованих посилань у цій темі:

  1. command.com - це 16-розрядний командний процесор, представлений в MS-DOS, а також використовувався в операційній системі Win9x.
  2. 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.
  3. ComSpecМінлива ENV визначає , яка програма запускається .batі .cmdскрипти. (Починаючи з WinNT для цього за замовчуванням cmd.exe.)
  4. cmd.exeє сумісним назад command.com.
  5. Сценарій, призначений для, 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) знаходяться в одній папці, і ви запускаєте скрипт без розширення (тест), за замовчуванням буде запущена версія .bat, навіть на 64-розрядної Windows 7. Порядок виконання контролюється змінною середовища PATHEXT. Див. Порядок, у якому командний рядок виконує файли для отримання більш детальної інформації.

Список літератури:

Вікіпедія: Порівняння командних оболонок


4
Кілька незначних моментів: 1) .bat не обов’язково викликає command.com - мабуть, коли виклику command.com є дещо складною таємницею; 2) було введено command.com з MS-DOS; 3) cmd.exe може запускати більшість скриптів command.com, але є кілька незначних речей command.com, які не працюють у cmd.
Майкл Берр

6
cmd.exe був представлений з NT 4.0 Я вважаю, а не Windows 95.
FlySwat

1
Кріс: дивіться поточну версію статті у Вікіпедії, особливо коментар Марка Збіковського на groups.google.com/group/…
Марк

2
Просто додати інформацію про цю проблему: dir filenameте саме, що dir filename.*в command.com; подвійну карту потрібно в cmd.exe. У command.com rem Create an empty file > empty.txtпрацює; не в cmd.exe.
Аакіні

2
Лише небагато цього, здається, має відношення до питання ОП, що стосується різниці між .bat та .cmd, а не різницею command.com та cmd.exe. Коли я читав, питання полягає в різниці між .bat файлом і .cmd файлом, при всіх інших рівнях.
Стюарт

85

Ці відповіді трохи занадто довгі та зосереджені на інтерактивному використанні. Важливі відмінності сценаріїв:

  • .cmd запобігає ненавмисному виконанню в системах, що не належать до NT.
  • .cmd дозволяє вбудованим командам змінювати помилку Errorle на 0 на успіх.

Не так захоплююче, так?

У .cmdфайлах раніше було включено ряд додаткових функцій , званих Command Extensions. Однак вони тепер увімкнено як для, так .batі для.cmd файлів в ОС Windows 2000 і вище.

Підсумок: у 2012 році і далі я рекомендую використовувати .cmdвиключно.


7
ІМО, це головний момент. Ви використовуєте .cmd як розширення для новіших сценаріїв, коли хочете переконатися, що вони не виконуються на старих 16-бітних ОС або якщо ви не впевнені, що вони працюватимуть.
Олівер

12
Я дуже ціную стислі, прагматичні та чіткі відповіді через багато стін непотрібних відповідей університетського класу.
Рідке ядро

7
Я викладач університету і згоден з @Liquid Core! Короткі, прагматичні, чіткі відповіді - це те, як ми вчимося (коли ще чогось не знаємо). Тоді якось, як тільки ми це зрозуміємо, ми відчуваємо бажання пояснити це абстрактно і незрозуміло. Дивно. Гарне спостереження!
Еврика

24

Ні - це не має ніякого значення. У 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-розрядна оболонка успадковує всі функції та засоби повної оболонки Windows NT.


5
Це може мати значення; оскільки згадується текст посилання, то відмінності є тонкими.
Gringo Suave

Ви можете змусити command.com виконати команду dos, вказавши її в командному рядку. Див. command /c verПроти запуску command.com та введення ver.
phd443322

Ім'я має значення: D Бачив багато .bat від хлопців з минулого! Використовуйте .cmd! Також не можу повірити, що NT використовується і сьогодні ...
hfrmobile

@hfrmobile: Коли я згадував "NT", я мав на увазі всі версії Windows, які базуються на NT (а не 9x). Таким чином, по суті, NT, Win2k та всі версії Windows для робочого столу чи сервера з XP. Ім'я файлу може дати зрозуміти стиль мислення та кодування людини, яка написала файл, але що стосується перекладача, то різниці немає.
Майкл Берр

16

RE: Мабуть, коли посилається command.com - це складна таємниця;

Кілька місяців тому під час проекту нам довелося з'ясувати, чому деякі програми, які ми хотіли запустити під CMD.EXE, насправді виконувались під COMMAND.COM. Програма, про яку йдеться, була дуже старим файлом .BAT, який все ще працює щодня.

Ми з'ясували, що причиною того, що пакетний файл запускався під COMMAND.COM, є те, що він запускався з .PIF-файлу (також давнього). Оскільки спеціальні параметри конфігурації пам’яті, доступні лише через PIF, стали неактуальними, ми замінили його звичайним ярликом на робочому столі.

Цей же пакетний файл, запущений із ярлика, працює у CMD.EXE. Коли ви думаєте про це, це має сенс. Причина того, що нам знадобилося стільки часу, щоб розібратися, була частково пов'язана з тим, що ми забули, що його предметом у групі стартапів був PIF, оскільки він був у виробництві з 1998 року.


1
Що це за ОС? Щось до XP?
phk

14

Однак у 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>

Це робиться тому, що test.bat в алфавітному порядку перед test.cmd. Windows робить жадібне завершення.
Девід

26
@David: Неправда. Це відбувається тому, що в PATHEXTзмінній розширення .BAT ставиться перед .CMD (як показано у цій відповіді). Якщо ви модифікуєте це замовлення в PATHEXT, замість цього буде виконуватися test.cmd.
Аакіні

Гм, я сподівався, що вони в іншому порядку; Я думаю, що MS, мабуть, виявив (або припустив), що деякі існуючі програмні продукти постачають файли .CMD та файли .BAT з тим самим базовим іменем, де .CMD файли, звичайно, не призначені як вхід для (ще не поставленого) cmd. exe, але це могла бути будь-яка кількість інших речей: команди для якоїсь іншої оболонки, сценарій конфігурації, прочитаний програмою, або якийсь бінарний додаток, наприклад. (Принаймні, це моє розуміння звичайного способу, коли MS закінчується, здавалося б, неоптимальною поведінкою.)
SamB

Також варто зазначити, що поточний каталог знаходиться перед іншими каталогами PATHзмінної середовища незалежно від розширення.
Turkeyphant

13

Оскільки початковий пост стосувався наслідків використання суфікса .bat або .cmd , не обов'язково команд всередині файлу ...

Ще одна відмінність між .bat і .cmd полягає в тому, що якщо два файли існують з тим самим ім'ям файлу та обома розширеннями, тоді:

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

  • щоб запустити .cmd файл, потрібно ввести ім'я файлу .cmd


2
Так? Якщо я поміщаю cmd-файл у свій dir, мені не потрібно вказувати розширення файлу, щоб викликати його. Приклад: echo notepad.exe% *> np.cmd Тоді, якщо я просто напишу "np mytextfilename.txt", він відобразить блокнот. Мені не потрібно вводити "np.cmd", щоб викликати його.
Джон Девіс

2
@ stimpy77: Це правда, якщо np.cmd - єдиний файл з таким ім'ям, але "якщо два файли існують з тим самим ім'ям файлу та обома розширеннями" , то єдиним способом виконання .cmd є включення його розширення. ..
Аакіні

1
Це необхідність вирішення двозначності для будь-якої оболонки, нічого спільного з технічними відмінностями між .cmd vs .bat. Можливо, тому що filename.bat передує filename.cmd в алфавітному порядку.
Джон Девіс

6
Це насправді залежить від PATHEXTзмінної середовища. Порядок, у якому з'являються розширення, є порядок пріоритетності, якщо розширення не вказано. Варто також зазначити, що не потрібно вказувати розширення для файлів, які його розширення відображається у змінній env.
Рікардо Зоріо

8

все, що працює в партії, повинно працювати в cmd; cmd надає деякі розширення для контролю навколишнього середовища. Крім того, cmd виконується в новому інтерпретаторі cmd і, таким чином, повинен бути швидшим (не помітно на коротких файлах) і стабільнішим, оскільки bat працює в умовах 16TV біту, імітованого NTVDM


Не слід змінювати швидкість. .batне працює під DOS в NT. VDM запускається лише в тому випадку, якщо програма потрібна, і навіть не підтримується в 64-бітовій Windows, хоча я вважаю, що .bat є.
Gringo Suave

3

Виконання файлу .cmd і .bat відрізняється тим, що в змінній .cmd errorlevel він може змінюватися в команді, на яку впливають розширення команд. Це про це насправді.


З грубої ^. ^ Існують відмінності в мові команд, що використовується для кожного (файли .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
zask

4
У файлах .cmd кожна команда встановлює рівень помилок, у файлах .bat деякі команди залишають рівень помилки незмінним, як це описано у прийнятій відповіді
jeb

1
BAT був створений для взаємодії з COMMAND.COM, інтерпретатором команд DOS. Microsoft прийняла більшість команд DOS у своєму новому інтерпретаторі під назвою CMD. EXE. CMD був створений для взаємодії з CMD.EXE, і він порушує сумісність із COMMAND.COM. в основному відомий тим, як вони обробляють змінну рівня помилок. При використанні BAT ця змінна змінюється лише після того, як відбувається фактична помилка і не відбувається зміни стану, коли кожна команда успішно виконується. Це не вірно для CMD, оскільки змінна рівня помилок все одно змінить стан, навіть якщо помилок не трапляється.
zask

3

Я вважаю, що якщо ви зміните значення змінної середовища ComSpec на %SystemRoot%system32\cmd.exe(CMD), то не має значення, чи є розширення файлу .BATабо .CMD. Я не впевнений, але це може бути навіть за замовчуванням для WinXP і вище.


1

Трохи поза темою, але ви вважали хост сценарію Windows ? Вам це може бути приємніше.


13
З цього приводу PowerShell, яка застаріло WSH / cscript.exe.
Джон Девіс

3
@ stimpy77 Щоправда, хоч powerhell мені здається досить жахливим.
Марцін

2
Я вважаю WSH набагато гірше. Я думаю, все залежить від того, що ми вимірюємо для "жахливих". PowerShell має жахливий час запуску. Все про нього абсолютно чудовий ІМО.
Джон Девіс

Вибачте від форматування, але щоб пришвидшити час запуску PSH, спробуйте запустити: Set-Alias ​​ngen @ (dir (join-path $ {env: \ windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -descending lastwritetime) [0] .fullName [НОВА ЛІНІЯ ТУТ] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
mjbnz

1
Цілком поза темою.
HappyDog

1

Розширення не має значення.

Існують невеликі відмінності між COMMAND.COMобробкою файлу та порівнянням CMD.EXE.


-10

різниця:

Файли .cmd завантажуються в пам'ять перед виконанням. .bat файли виконують рядок, читають наступний рядок, виконують цей рядок ...

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


Як було встановлено, змінна ComSpec env визначає, яка програма запускається? Ви, по суті, говорите, що command.com читає файл одночасно, а cmd.exe попередньо завантажує файл у пам'ять? Чи можете ви навести посилання на це?
Кріс Ное

24
Це неправильно для Vista та XP, обидва типи файлів читаються по черзі. Якщо ви призупините файл .cmd або .bat і відредагуєте його, буде виконано новий код
виконаний jeb


1
Можна обговорити, чи це рядок за рядком, тому що якщо ви призупинили виконання в середині командного файлу та додали символ на початку, після відновлення парсер буде вимкнений одним символом, можливо, скинувши решту вашого сценарію.

2
Ви не повинні обговорювати .bat і .cmd не відрізняється таким чином. Обидва завжди читаються рядок за рядком. Ви можете протестувати, якщо не вірите. Створіть пакетний файл, який echo 1&pauseпотім виконує його. Ви побачите 1і Press any key to continue.... Під час паузи додайте новий рядок echo 2&pauseіз зовнішнім редактором. Натисніть клавішу. Ви побачите 2і Press any key to continue.... Можна навіть спробувати додати echo 3&pauseна початку. Коли ви знову натиснете клавішу, ви побачите 2.
venimus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.