Pliki wsadowe systemu Windows: .bat vs .cmd?


747

Jak rozumiem, .batjest to stara 16-bitowa konwencja nazewnictwa, i .cmddotyczy 32-bitowego systemu Windows, tj. Zaczynającego się od NT. Ale nadal widzę pliki .bat wszędzie i wydaje się, że działają dokładnie tak samo, używając jednego z sufiksów. Zakładając, że mój kod nie będzie trzeba uruchomić na coś starszego niż NT, to naprawdę ważne, w jaki sposób mogę wymienić moje pliki wsadowe, czy jest jakiś haczyka w oczekiwaniu na mnie zły za pomocą przyrostka?


19
Żeby dodać zamieszanie, teraz mamy również pliki .ps1.
— Martin Brown

42
jeśli się nie mylę, pliki .ps1 powinny być plikami Windows Power Shell. Mogę się jednak mylić.
— CMS_95

Odpowiedzi:


454

Z tego posta opublikowanego przez samego Marka Zbikowskiego :

Różnice między .CMD i .BAT w odniesieniu do CMD.EXE są następujące: Przy włączonych rozszerzeniach PATH / APPEND / PROMPT / SET / ASSOC w plikach .CMD ustawi ERRORLEVEL bez względu na błąd. .BAT ustawia ERRORLEVEL tylko w przypadku błędów.

Innymi słowy, jeśli ERRORLEVEL ma wartość inną niż 0, a następnie uruchomisz jedno z tych poleceń, wynikowy ERRORLEVEL będzie:

  • pozostawione same sobie z wartością inną niż 0 w pliku bat
  • zresetować do 0 w pliku .cmd.

4
Czy to oznacza, że ​​użycie skryptu .bat nie zwróci wartości ERRORLEVEL 0 w przypadku powodzenia? Jeśli to prawda, nigdy tego nie zauważyłem.
— djangofan

31
Myślę, że oznacza to, że jeśli ERRORLEVEL był ustawiony na wartość inną niż 0, to uruchomisz jedną z tych komend, pozostanie ona sama (inna niż 0) w pliku .bat, ale zresetuje się do 0 w pliku .cmd. Ale ponieważ Windows jest tym, czym jest, jest całkiem możliwe, że w rzeczywistości powoduje to bezcielesny głos w Pig Latin, „zresetuj się, jeśli tak bardzo ci zależy!”.
— MadScientist

5
Myślę, że to mówi, że tylko te konkretne polecenia wykonałyby różne akcje ustawiania / nie ustawiania. Inni będą działać normalnie
— PsychoData

1
Teraz rozumiem. Zaktualizowałem swoją treść. Najwyraźniej nie ustawia poziomu błędu podczas wywoływania set var=..instrukcji. Co jest dziwne, ponieważ założyłem, że było to oczekiwane zachowanie. Można argumentować na oba sposoby. Zostanę przy plikach .bat. :-)
— wasatchwizard

1
Uwaga - polecenie APPEND zostało zastąpione nieudokumentowanym poleceniem DPATH, chociaż DPATH /?nadal wyświetla polecenie jako APPEND. Ponadto artykuł na Wiki został w większości poprawiony, z tym wyjątkiem, że nie zawiera DPATH.
— dbenham

417

Oto zestawienie zweryfikowanych informacji z różnych odpowiedzi i cytowanych referencji w tym wątku:

  1. command.com to 16-bitowy procesor poleceń wprowadzony w MS-DOS i był również używany w systemach operacyjnych z serii Win9x.
  2. cmd.exeto 32-bitowy procesor poleceń w systemie Windows NT (64-bitowe systemy operacyjne Windows mają również wersję 64-bitową). cmd.exenigdy nie był częścią systemu Windows 9x. Powstał w wersji OS / 2 1.0, a wersja OS / 2 cmdrozpoczęła 16-bit (ale mimo to był w pełni rozwiniętym programem w trybie chronionym z podobnymi poleceniami start). Windows NT odziedziczył cmdpo OS / 2, ale wersja Win32 systemu Windows NT rozpoczęła się od wersji 32-bitowej. Mimo że OS / 2 przeszedł na wersję 32-bitową w 1992 roku, cmdpozostał 16-bitowym programem OS / 2 1.x.
  3. ComSpecZmienne env definiuje, jaki program jest uruchomiony przez .bati .cmdskrypty. (Począwszy od WinNT, domyślnie jest to cmd.exe.)
  4. cmd.exejest wstecznie kompatybilny z command.com.
  5. Zaprojektowany skrypt cmd.exemożna nazwać, .cmdaby zapobiec przypadkowemu uruchomieniu w systemie Windows 9x. To rozszerzenie nazwy pliku pochodzi także z wersji OS / 2 1.0 i 1987.

Oto lista cmd.exefunkcji, które nie są obsługiwane przez command.com:

  • Długie nazwy plików (przekraczające format 8.3)
  • Historia dowodzenia
  • Uzupełnianie tabulatorów
  • Znak ucieczki: ^(Użyj dla \ & | > < ^:)
  • Stos katalogów: PUSHD/POPD
  • Arytmetyka liczb całkowitych: SET /A i+=1
  • Wyszukaj / Zamień / Podciąg: SET %varname:expression%
  • Podstawianie poleceń: FOR /F(istniało wcześniej, zostało ulepszone)
  • Funkcje: CALL :label

Kolejność wykonania:

Jeśli obie wersje skryptu .bat i .cmd (test.bat, test.cmd) znajdują się w tym samym folderze i uruchomisz skrypt bez rozszerzenia (test), domyślnie uruchomiona zostanie wersja .bat skryptu, nawet w 64-bitowym systemie Windows 7. Kolejność wykonywania jest kontrolowana przez zmienną środowiskową PATHEXT. Aby uzyskać więcej informacji, zobacz Kolejność, w której wiersz polecenia wykonuje pliki .

Bibliografia:

wikipedia: Porównanie powłok poleceń


4
Kilka drobnych punktów: 1) .bat niekoniecznie wywołuje Command.com - najwyraźniej, gdy wywoływane jest polecenie Command.com, jest to trochę skomplikowana tajemnica; 2) Command.com zostało wprowadzone w MS-DOS; 3) cmd.exe może uruchamiać większość skryptów command.com, ale istnieje kilka drobnych rzeczy, które nie działają w cmd.
— Michael Burr,

6
cmd.exe został wprowadzony wraz z NT 4.0, nie Windows 95.
— FlySwat

1
Chris: zobacz aktualną wersję artykułu z Wikipedii, szczególnie. komentarz Marka Zbikowskiego na groups.google.com/group/…
— Mark

2
Wystarczy dodać trochę informacji na ten temat: dir filenamejest taki sam jak dir filename.*w command.com; symbol wieloznaczny jest wymagany w cmd.exe. W Command.com rem Create an empty file > empty.txtdziała; nie w cmd.exe.
— Aacini

2
Tylko niewielka część tego wydaje się być istotna dla pytania OP, które dotyczy różnicy między .bat i .cmd, a nie różnicy między Command.com i cmd.exe. Kiedy czytam, pytanie dotyczy różnicy między plikiem .bat a plikiem .cmd, przy czym wszystkie inne rzeczy są takie same.
— Stewart

85

Te odpowiedzi są nieco za długie i koncentrują się na interaktywnym użyciu. Ważnymi różnicami dla skryptów są:

  • .cmd zapobiega niezamierzonemu wykonaniu w systemach innych niż NT.
  • .cmd włącza wbudowane polecenia zmiany poziomu błędu na 0 po sukcesie.

Nie takie ekscytujące, prawda?

Kiedyś w .cmdplikach włączono wiele dodatkowych funkcji , zwanych rozszerzeniami poleceń. Jednak są one teraz domyślnie włączone zarówno dla plików, jak .bati dla .cmdsystemu Windows 2000 i nowszych.

Podsumowując: w 2012 roku i później polecam używać .cmdwyłącznie.


7
IMO, to jest główny punkt. Pliku .cmd używasz jako rozszerzenia dla nowszych skryptów, gdy chcesz się upewnić, że nie są one uruchamiane w starszych 16-bitowych systemach operacyjnych lub jeśli nie masz pewności, czy będą działać.
— Oliver

12
Naprawdę doceniam zwięzłe, pragmatyczne i jasne odpowiedzi ponad tonami ścian bezużytecznych odpowiedzi uniwersyteckich.
— Liquid Core

7
Jestem profesorem uniwersyteckim i zgadzam się z @Liquid Core! W ten sposób uczymy się zwięzłych, pragmatycznych i jasnych odpowiedzi (kiedy czegoś jeszcze nie wiemy). Potem, gdy to zrozumiemy, odczuwamy potrzebę wyjaśnienia go w sposób abstrakcyjny i niezrozumiały. Dziwne. Dobra obserwacja!
— Eureka

24

Nie - nie ma to najmniejszego znaczenia. W NT rozszerzenie .bat i .cmd powodują, że procesor cmd.exe przetwarza plik dokładnie w ten sam sposób.

Dodatkowe interesujące informacje o Command.com vs. cmd.exe w systemach klasy WinNT od MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx ):

To zachowanie ujawnia dość subtelną funkcję systemu Windows NT, która jest bardzo ważna. 16-bitowa powłoka MS-DOS (COMMAND.COM) dostarczana z systemem Windows NT jest specjalnie zaprojektowana dla systemu Windows NT. Gdy polecenie zostanie wprowadzone w celu wykonania przez tę powłokę, faktycznie go nie wykonuje. Zamiast tego pakuje tekst polecenia i wysyła go do 32-bitowej powłoki poleceń CMD.EXE w celu wykonania. Ponieważ wszystkie polecenia są w rzeczywistości wykonywane przez CMD.EXE (powłokę poleceń systemu Windows NT), 16-bitowa powłoka dziedziczy wszystkie funkcje i funkcje pełnej powłoki systemu Windows NT.


5
To może mieć znaczenie; jak wspomina tekst linku, różnice są subtelne.
— Gringo Suave,

Możesz zmusić command.com do wykonania polecenia dos, określając je w wierszu poleceń. Zobacz command /c verkontra uruchomienie command.com i wpisanie ver.
— phd443322

Nazwa ma znaczenie: D Widziałem wiele .bat od facetów z przeszłości! Użyj .cmd! Nie mogę też uwierzyć, że NT jest nadal używany dzisiaj ...
— hfrmobile 16.04.15

@hfrmobile: Kiedy wspomniałem o „NT”, miałem na myśli zasadniczo wszystkie wersje systemu Windows, które bazujemy na NT (a nie 9x). Tak więc w zasadzie NT, Win2k i wszystkie wersje systemu Windows na komputer lub serwer od XP. Nazwa pliku może dać wgląd w sposób myślenia i styl kodowania osoby, która napisała plik, ale jeśli chodzi o tłumacza, nie ma różnicy.
— Michael Burr

16

RE: Najwyraźniej, kiedy wywoływane jest polecenie command.com, jest to trochę skomplikowana tajemnica;

Kilka miesięcy temu, w trakcie projektu, musieliśmy dowiedzieć się, dlaczego niektóre programy, które chcieliśmy uruchomić pod CMD.EXE, faktycznie działały pod COMMAND.COM. „Program”, o którym mowa, był bardzo starym plikiem .BAT, który wciąż działa codziennie.

Odkryliśmy, że powodem, dla którego plik wsadowy działał w COMMAND.COM, jest to, że był uruchamiany z pliku .PIF (również starożytnego). Ponieważ specjalne ustawienia konfiguracji pamięci dostępne tylko przez PIF stały się nieistotne, zastąpiliśmy je konwencjonalnym skrótem na pulpicie.

Ten sam plik wsadowy, uruchomiony ze skrótu, działa w programie CMD.EXE. Kiedy się nad tym zastanowić, ma to sens. Powodem, dla którego tak długo nam to zajęło, było częściowo to, że zapomnieliśmy, że jego pozycją w grupie startupowej był MTP, ponieważ jest produkowany od 1998 roku.


1
Jaki to był system operacyjny? Coś przed XP?
— phk

14

Jednak w systemie Windows 7 pliki BAT mają również tę różnicę: jeśli kiedykolwiek utworzysz pliki TEST.BAT i TEST.CMD w tym samym katalogu i uruchomisz TEST w tym katalogu, uruchomi on plik 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>

Robi to, ponieważ test.bat jest alfabetycznie przed test.cmd. Windows robi chciwe zakończenie.
— David

26
@David: Nieprawda. Dzieje się tak, ponieważ w PATHEXTzmiennej rozszerzenie .BAT jest umieszczane przed .CMD jeden (jak pokazano w tej odpowiedzi). Jeśli zmodyfikujesz tę kolejność w PATHEXT, zamiast tego zostanie wykonany test.cmd.
— Aacini

Hmm, miałem nadzieję, że są w innej kolejności; Wydaje mi się, że MS musiał odkryć (lub założyć), że niektóre istniejące oprogramowanie dostarczało pliki .CMD i .BAT z tą samą nazwą basename, gdzie pliki .CMD nie były oczywiście przeznaczone jako dane wejściowe dla (jeszcze nie dostarczonego) cmd. exe, ale może to być dowolna liczba innych rzeczy: na przykład polecenia dla innej powłoki, skrypt konfiguracyjny odczytywany przez aplikację lub jakiś plik binarny aplikacji. (Przynajmniej takie jest moje rozumienie zwykłego sposobu, w jaki stwardnienie rozsiane kończy się z pozornie nieoptymalnym zachowaniem.)
— SamB

Warto również zauważyć, że bieżący katalog znajduje się przed innymi katalogami w PATHzmiennej środowiskowej niezależnie od rozszerzenia.
— Turkeyphant,

13

Ponieważ oryginalny post dotyczył konsekwencji użycia sufiksu .bat lub .cmd , niekoniecznie polecenia w pliku ...

Inną różnicą między .bat i .cmd jest to, że jeśli istnieją dwa pliki o tej samej nazwie i obu rozszerzeniach, to:

  • wprowadzenie nazwy pliku lub pliku .bat w wierszu polecenia spowoduje uruchomienie pliku .bat

  • aby uruchomić plik .cmd, musisz wprowadzić nazwę pliku .cmd


2
Co? Jeśli wstawię plik cmd do katalogu, nie muszę określać rozszerzenia pliku, aby go wywołać. Przykład: echo notepad.exe% *> np.cmd Następnie po wpisaniu „np mytextfilename.txt” pojawi się notatnik. Nie muszę wpisywać „np.cmd”, aby go wywołać.
— Jon Davis,

2
@ stimpy77: Jest to prawdą, jeśli np.cmd jest jedynym plikiem o tej nazwie, ale „jeśli istnieją dwa pliki o tej samej nazwie i obu rozszerzeniach” , jedynym sposobem na uruchomienie .cmd jest dołączenie jego rozszerzenia. ..
— Aacini

1
Jest to konieczność rozwiązania niejednoznaczności każdej powłoki, nie ma to nic wspólnego z technicznymi różnicami między .cmd a .bat. Prawdopodobnie dlatego, że nazwa_pliku.bat poprzedza nazwa pliku.cmd alfabetycznie.
— Jon Davis,

6
To zależy od PATHEXTzmiennej środowiskowej. Kolejność wyświetlania rozszerzeń jest kolejnością pierwszeństwa, jeśli rozszerzenie nie jest określone. Warto również wspomnieć, że nie jest konieczne określanie rozszerzenia dla plików, których rozszerzenie pojawia się w zmiennej env.
— Ricardo Zorio,

8

wszystko działające w partii powinno działać w cmd; cmd zapewnia pewne rozszerzenia do kontrolowania środowiska. cmd jest również wykonywany przez nowy interpreter cmd i dlatego powinien być szybszy (niewidoczny na krótkich plikach) i stabilny, ponieważ bat działa w środowisku 16-bitowym emulowanym NTVDM


Nie powinno mieć znaczenia różnica prędkości. .batnie działa pod DOS-em w NT. VDM jest uruchamiany tylko wtedy, gdy program go potrzebuje, i nie jest nawet obsługiwany w 64-bitowym systemie Windows, chociaż uważam, że .bat jest.
— Gringo Suave,

3

Wykonywanie plików .cmd i .bat jest inne, ponieważ w zmiennej poziomu błędu .cmd może zmieniać się w przypadku polecenia, którego dotyczą rozszerzenia poleceń. To naprawdę o to chodzi.


Z grubej ^. ^ Istnieją różnice w języku poleceń używanym dla każdego (pliki .bat otrzymują wersję kompatybilności). Niektóre z nich można zilustrować stąd: @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
— zaskoczyć

4
W plikach .cmd każde polecenie ustawia poziom błędu, w plikach .bat niektóre polecenia pozostawiają poziom błędu bez zmian, jak opisano w zaakceptowanej odpowiedzi
— jeb

1
BAT został stworzony do współpracy z COMMAND.COM, interpreterem poleceń DOS. Microsoft zaadaptował większość poleceń DOS do swojego nowego interpretera o nazwie CMD. EXE. CMD został stworzony do współpracy z CMD.EXE i łamie kompatybilność z COMMAND.COM. znany głównie z tego, jak obsługują zmienną poziomu błędu. Podczas korzystania z BAT zmienna ta jest zmieniana tylko wtedy, gdy wystąpi rzeczywisty błąd i nie nastąpi zmiana stanu, gdy każde polecenie zostanie wykonane pomyślnie. Nie dotyczy to CMD, ponieważ zmienna poziomu błędu nadal zmienia stan, nawet jeśli nie wystąpią żadne błędy.
— zask

3

Uważam, że jeśli zmienisz wartość zmiennej środowiskowej ComSpec na %SystemRoot%system32\cmd.exe(CMD), to nie ma znaczenia, czy rozszerzenie pliku to .BATlub .CMD. Nie jestem pewien, ale może nawet być domyślny dla WinXP i wyższych.


1

Nieco temat, ale czy zastanawiałeś się nad hostem skryptów Windows ? Możesz znaleźć to ładniejsze.


13
W tym przypadku PowerShell, który zastępuje WSH / cscript.exe.
— Jon Davis,

3
@ stimpy77 To prawda, chociaż PowerShell wydaje mi się dość okropny.
— Marcin

2
Uważam, że WSH jest znacznie gorszy. Przypuszczam, że wszystko zależy od tego, co oceniamy jako „okropne”. PowerShell ma okropny czas uruchamiania. Wszystko w tym jest absolutnie cudowne IMO.
— Jon Davis,

Przepraszam za formatowanie, ale aby przyspieszyć uruchomienie PSH, spróbuj uruchomić: Set-Alias ​​ngen @ (reż (join-path $ {env: \ windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -descending lastwritetime) [0] .fullName [NEW LINE HERE] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
— mjbnz

1
Zupełnie nie na temat.
— HappyDog,

1

Rozszerzenie nie ma znaczenia.

Istnieją niewielkie różnice między COMMAND.COMobsługą pliku a CMD.EXE.


-10

różnica:

Pliki .cmd są ładowane do pamięci przed uruchomieniem. Pliki .bat wykonują wiersz, czytają następny wiersz, wykonują ten wiersz ...

możesz zetknąć się z tym, wykonując plik skryptu, a następnie edytując go, zanim zakończy się wykonywanie. pliki bat będą przez to pomieszane, ale pliki cmd nie.


Jak ustalono, zmienna ComSpec env określa, który program jest uruchamiany, czy w gruncie rzeczy mówisz, że command.com czyta plik po linii, a cmd.exe wstępnie ładuje plik do pamięci? Czy możesz zacytować referencje na ten temat?
— Chris Noe,

24
To jest złe dla Vista i XP, oba typy plików są odczytywane linia po linii. Jeśli wstrzymasz plik .cmd lub .bat i go edytujesz, nowy kod zostanie wykonany
— jeb


1
Można dyskutować, czy wiersz po wierszu, ponieważ jeśli wstrzymasz wykonywanie w środku pliku poleceń i dodasz znak na początku, po wznowieniu parser zostanie wyłączony o jeden znak, prawdopodobnie odrzucając resztę skryptu.

2
Nie powinieneś debatować .bat i .cmd nie różnią się w ten sposób. Oba są zawsze odczytywane linia po linii. Możesz to przetestować, jeśli nie wierzysz. Utwórz plik wsadowy, który echo 1&pausenastępnie go uruchomi. Zobaczysz 1i Press any key to continue.... Podczas wstrzymania dodaj nową linię za echo 2&pausepomocą zewnętrznego edytora. Naciśnij klawisz. Zobaczysz 2i Press any key to continue.... Możesz nawet spróbować dodać echo 3&pausena początku. Po ponownym naciśnięciu klawisza zobaczysz 2.
— venimus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.