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?

Chris Noe
źródło
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.
Ben Hoffstein
źródło
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ń

Chris Noe
źródło
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.

Gringo Suave
źródło
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.

Michael Burr
źródło
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.

David Gray
źródło
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>
tvCa
źródło
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

Rob w TVSeries.com
źródło
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

Lorenzo Boccaccia
źródło
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.

zask
źródło
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.

Patrick Mankiet
źródło
1

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

Marcin
źródło
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.

Waldo
źródło
-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.

szary
źródło
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