Windows-Batchdateien: .bat vs .cmd?

747

Soweit ich weiß, .batist dies die alte 16-Bit-Namenskonvention und .cmdgilt für 32-Bit-Windows, dh beginnend mit NT. Aber ich sehe weiterhin überall .bat-Dateien, und sie scheinen mit beiden Suffixen genau gleich zu funktionieren. Unter der Annahme, dass mein Code niemals auf etwas älterem als NT ausgeführt werden muss, spielt es dann wirklich eine Rolle, wie ich meine Batch-Dateien benenne , oder wartet ein Gotcha auf mich, wenn ich das falsche Suffix verwende?

Chris Noe
quelle
19
Um die Verwirrung noch zu verstärken, haben wir jetzt auch .ps1-Dateien.
Martin Brown
42
Wenn ich mich nicht irre, sollten .ps1-Dateien eine Windows Power Shell-Datei sein. Ich könnte mich jedoch irren.
CMS_95

Antworten:

454

Aus dieser Newsgroup-Veröffentlichung von Mark Zbikowski selbst:

Die Unterschiede zwischen .CMD und .BAT in Bezug auf CMD.EXE sind: Bei aktivierten Erweiterungen setzt PATH / APPEND / PROMPT / SET / ASSOC in .CMD-Dateien ERRORLEVEL unabhängig vom Fehler. .BAT setzt ERRORLEVEL nur bei Fehlern.

Mit anderen Worten, wenn ERRORLEVEL auf ungleich 0 gesetzt ist und Sie dann einen dieser Befehle ausführen, lautet der resultierende ERRORLEVEL:

  • allein gelassen bei einem Wert ungleich 0 in einer .bat-Datei
  • in einer .cmd-Datei auf 0 zurücksetzen.
Ben Hoffstein
quelle
4
Bedeutet dies, dass die Verwendung eines .bat-Skripts bei einem Erfolg keinen ERRORLEVEL 0-Wert zurückgibt? Wenn das stimmt, habe ich es nie bemerkt.
Djangofan
31
Ich denke, es bedeutet, dass wenn ERRORLEVEL auf ungleich 0 gesetzt wurde und Sie einen dieser Befehle ausführen, dieser in einer .bat-Datei allein gelassen wird (nicht 0), in einer .cmd-Datei jedoch auf 0 zurückgesetzt wird. Da Windows das ist, was es ist, ist es durchaus möglich, dass eine körperlose Stimme Ihnen in Pig Latin sagt: "Setzen Sie ERRORLEVEL selbst zurück, wenn Sie sich so sehr darum kümmern!".
MadScientist
5
Ich denke, es heißt, dass nur diese spezifischen Befehle die verschiedenen Set / Not-Set-Aktionen ausführen würden. Andere werden wie
gewohnt
1
Ich verstehe jetzt. Ich habe meinen Kern aktualisiert. Anscheinend wird die Fehlerstufe beim Aufrufen einer set var=..Anweisung nicht (neu) festgelegt . Was seltsam ist, weil ich angenommen habe, dass das Verhalten erwartet wurde. Für beide könnten Argumente vorgebracht werden. Ich bleibe bei .bat-Dateien. :-)
Wasatchwizard
1
Hinweis - Der Befehl APPEND wurde durch den Befehl DPATH ohne Papiere ersetzt, obwohl DPATH /?der Befehl weiterhin als APPEND aufgeführt ist. Außerdem wurde der Wiki-Artikel inzwischen größtenteils korrigiert, außer dass DPATH nicht aufgeführt ist.
Dbenham
417

Hier ist eine Zusammenstellung verifizierter Informationen aus den verschiedenen Antworten und zitierten Referenzen in diesem Thread:

  1. command.com ist der in MS-DOS eingeführte 16-Bit-Befehlsprozessor, der auch in der Win9x-Reihe von Betriebssystemen verwendet wurde.
  2. cmd.exeist der 32-Bit-Befehlsprozessor in Windows NT (64-Bit-Windows-Betriebssysteme haben auch eine 64-Bit-Version). cmd.exewar nie Teil von Windows 9x. Es entstand in OS / 2 Version 1.0 und die OS / 2-Version von cmdbegann 16-Bit (war aber dennoch ein vollwertiges Programm im geschützten Modus mit Befehlen wie start). Windows NT wurde cmdvon OS / 2 geerbt , aber die Win32-Version von Windows NT wurde mit 32-Bit gestartet. Obwohl OS / 2 1992 auf 32-Bit umgestellt wurde, cmdblieb es ein 16-Bit-OS / 2 1.x-Programm.
  3. Das ComSpecenv Variable definiert , welches Programm durch gestartet .batund .cmdSkripten. (Beginnend mit WinNT ist dies standardmäßig cmd.exe.)
  4. cmd.exeist abwärtskompatibel mit command.com.
  5. Ein Skript, für das entwickelt wurde, cmd.exekann benannt werden .cmd, um eine versehentliche Ausführung unter Windows 9x zu verhindern. Diese Dateinamenerweiterung stammt ebenfalls aus OS / 2 Version 1.0 und 1987.

Hier ist eine Liste von cmd.exeFunktionen, die nicht unterstützt werden von command.com:

  • Lange Dateinamen (über dem 8.3-Format)
  • Befehlsverlauf
  • Tab-Vervollständigung
  • Escape-Zeichen: ^(Verwendung für:\ & | > < ^ )
  • Verzeichnisstapel: PUSHD/POPD
  • Ganzzahlige Arithmetik: SET /A i+=1
  • Suchen / Ersetzen / Teilzeichenfolge: SET %varname:expression%
  • Befehlsersetzung: FOR /F (existierte vorher, wurde erweitert)
  • Funktionen: CALL :label

Ausführungsreihenfolge:

Wenn sich sowohl die .bat- als auch die .cmd-Version eines Skripts (test.bat, test.cmd) im selben Ordner befinden und Sie das Skript ohne die Erweiterung (test) ausführen, wird standardmäßig sogar die .bat-Version des Skripts ausgeführt unter 64-Bit-Windows 7. Die Ausführungsreihenfolge wird von der Umgebungsvariablen PATHEXT gesteuert. Siehe Reihenfolge, in der die Eingabeaufforderung Dateien ausführtWeitere Informationen finden .

Verweise:

wikipedia: Vergleich von Befehls-Shells

Chris Noe
quelle
4
Einige kleinere Punkte: 1) .bat ruft nicht unbedingt command.com auf - anscheinend ist das Aufrufen von command.com ein komplexes Rätsel. 2) command.com wurde mit MS-DOS eingeführt; 3) cmd.exe kann die meisten command.com-Skripte ausführen, aber es gibt einige kleinere command.com-Dinge, die in cmd nicht funktionieren.
Michael Burr
6
cmd.exe wurde mit NT 4.0 eingeführt, glaube ich, nicht mit Windows 95.
FlySwat
1
Chris: siehe die aktuelle Version des Wikipedia-Artikels, insb. der Kommentar von Mark Zbikowski unter groups.google.com/group/…
Mark
2
Nur um einige Informationen zu diesem Thema hinzuzufügen: dir filenameist das gleiche wie dir filename.*in command.com; Der Platzhalter ist in cmd.exe erforderlich. In command.com rem Create an empty file > empty.txtfunktioniert; nicht in cmd.exe.
Aacini
2
Nur ein kleiner Teil davon scheint für die Frage des OP relevant zu sein, bei der es um den Unterschied zwischen .bat und .cmd geht, nicht um den Unterschied zwischen command.com und cmd.exe. Während ich es lese, geht es um den Unterschied zwischen einer .bat-Datei und einer .cmd-Datei, wobei alle anderen Dinge gleich sind.
Stewart
85

Diese Antworten sind etwas zu lang und konzentrieren sich auf die interaktive Verwendung. Die wichtigen Unterschiede für die Skripterstellung sind:

  • .cmd verhindert versehentliche Ausführung auf Nicht-NT-Systemen.
  • .cmd Aktiviert integrierte Befehle, um die Fehlerstufe bei Erfolg auf 0 zu ändern.

Nicht so aufregend, oder?

Früher waren in .cmdDateien eine Reihe zusätzlicher Funktionen aktiviert , die als Befehlserweiterungen bezeichnet wurden. Sie sind jetzt jedoch standardmäßig sowohl für .batals auch für .cmdDateien unter Windows 2000 und höher aktiviert .

Fazit: 2012 und darüber hinaus empfehle ich die .cmdausschließliche Verwendung .

Gringo Suave
quelle
7
IMO, das ist der Hauptpunkt. Sie verwenden .cmd als Erweiterung für neuere Skripte, wenn Sie sicherstellen möchten, dass sie auf älteren 16-Bit-Betriebssystemen nicht ausgeführt werden, oder wenn Sie nicht sicher sind, ob sie funktionieren.
Oliver
12
Ich schätze prägnante, pragmatische und klare Antworten über Tonnen von Wänden nutzloser, universitätsähnlicher Antworten.
Liquid Core
7
Ich bin Universitätsprofessor und stimme @Liquid Core zu! Prägnante, pragmatische und klare Antworten sind, wie wir lernen (wenn wir noch nichts wissen). Sobald wir es verstanden haben, verspüren wir irgendwie den Drang, es abstrakt und unverständlich zu erklären. Seltsam. Gute Beobachtung!
Eureka
24

Nein - es spielt keine Rolle. Unter NT bewirken die Erweiterung .bat und .cmd, dass der Prozessor cmd.exe die Datei genauso verarbeitet.

Zusätzliche interessante Informationen zu command.com vs. cmd.exe auf Systemen der WinNT-Klasse von MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx ):

Dieses Verhalten zeigt eine sehr subtile Funktion von Windows NT, die sehr wichtig ist. Die mit Windows NT gelieferte 16-Bit-MS-DOS-Shell (COMMAND.COM) wurde speziell für Windows NT entwickelt. Wenn ein Befehl zur Ausführung durch diese Shell eingegeben wird, wird er nicht ausgeführt. Stattdessen packt es den Befehlstext und sendet ihn zur Ausführung an eine 32-Bit-CMD.EXE-Befehlsshell. Da alle Befehle tatsächlich von CMD.EXE (der Windows NT-Befehlsshell) ausgeführt werden, erbt die 16-Bit-Shell alle Funktionen und Möglichkeiten der vollständigen Windows NT-Shell.

Michael Burr
quelle
5
Es kann wichtig sein; Wie in Ihrem Linktext erwähnt, sind die Unterschiede subtil.
Gringo Suave
Sie können command.com zwingen, einen dos-Befehl auszuführen, indem Sie ihn in der Befehlszeile angeben. Siehe command /c verversus Starten von command.com und Eingeben von ver.
Phd443322
Name zählt: D Ich habe gesehen, dass viele .bat von Jungs aus der Vergangenheit stammen! Verwenden Sie .cmd!
Ich
@hfrmobile: Als ich 'NT' erwähnte, meinte ich im Grunde alle Windows-Versionen, die auf NT basieren (und nicht 9x). Also im Wesentlichen NT, Win2k und alle Windows-Versionen für den Desktop oder Server seit XP. Und der Name der Datei gibt möglicherweise einen Einblick in die Denkweise und den Codierungsstil der Person, die die Datei geschrieben hat, aber für den Interpreter gibt es keinen Unterschied.
Michael Burr
16

RE: Anscheinend ist das Aufrufen von command.com ein komplexes Rätsel.

Vor einigen Monaten mussten wir im Verlauf eines Projekts herausfinden, warum einige Programme, die wir unter CMD.EXE ausführen wollten, tatsächlich unter COMMAND.COM ausgeführt wurden. Das fragliche "Programm" war eine sehr alte .BAT-Datei, die immer noch täglich ausgeführt wird.

Wir haben festgestellt, dass die Batch-Datei unter COMMAND.COM ausgeführt wurde, weil sie aus einer .PIF-Datei (ebenfalls uralt) gestartet wurde. Da die speziellen Speicherkonfigurationseinstellungen, die nur über ein PIF verfügbar sind, irrelevant geworden sind, haben wir sie durch eine herkömmliche Desktop-Verknüpfung ersetzt.

Dieselbe Batchdatei, die über die Verknüpfung gestartet wurde, wird in CMD.EXE ausgeführt. Wenn Sie darüber nachdenken, ist dies sinnvoll. Der Grund, warum wir so lange gebraucht haben, um es herauszufinden, war teilweise die Tatsache, dass wir vergessen hatten, dass es sich bei dem Artikel in der Startup-Gruppe um ein PIF handelte, da es seit 1998 in Produktion war.

David Gray
quelle
1
Welches Betriebssystem war das? Etwas vor XP?
Phk
14

Unter Windows 7 weisen BAT-Dateien jedoch auch diesen Unterschied auf: Wenn Sie jemals Dateien TEST.BAT und TEST.CMD im selben Verzeichnis erstellen und TEST in diesem Verzeichnis ausführen, wird die BAT-Datei ausgeführt.

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
quelle
Dies geschieht, weil test.bat alphabetisch vor test.cmd steht. Windows macht gierige Fertigstellung.
David
26
@ David: Nicht wahr. Dies geschieht, weil in der PATHEXTVariablen die Erweiterung .BAT vor der Erweiterung .CMD steht (wie in dieser Antwort gezeigt). Wenn Sie diese Reihenfolge in PATHEXT ändern, wird stattdessen die Datei test.cmd ausgeführt.
Aacini
Hmm, ich hatte gehofft, dass sie in der anderen Reihenfolge waren; Ich denke, MS muss entdeckt (oder angenommen) haben, dass einige vorhandene Software .CMD-Dateien und .BAT-Dateien mit demselben Basisnamen ausgeliefert hat, wobei die .CMD-Dateien natürlich nicht als Eingabe für die (noch nicht ausgelieferte) cmd gedacht waren. exe, könnte aber auch eine Reihe anderer Dinge sein: Befehle für eine andere Shell, ein von der Anwendung gelesenes Konfigurationsskript oder eine Art Anwendungsbinärdatei. (Zumindest ist das mein Verständnis der üblichen Art und Weise, wie MS zu einem scheinbar nicht optimalen Verhalten führt.)
SamB
Es ist auch erwähnenswert, dass das aktuelle Verzeichnis PATHunabhängig von der Erweiterung vor anderen Verzeichnissen in der Umgebungsvariablen steht.
Truthahn
13

Da der ursprüngliche Beitrag wurde in Bezug auf die Folgen der .bat oder .cmd mit Suffix , die nicht unbedingt die Befehle innerhalb der Datei ...

Ein weiterer Unterschied zwischen .bat und .cmd besteht darin, dass, wenn zwei Dateien mit demselben Dateinamen und diesen beiden Erweiterungen vorhanden sind:

  • Eingabe Dateinamen oder Dateinamen BAT in der Befehlszeile wird die BAT - Datei auszuführen

  • Um die .cmd-Datei auszuführen, müssen Sie den Dateinamen .cmd eingeben

Rob bei TVSeries.com
quelle
2
Eh? Wenn ich eine Cmd-Datei in mein Verzeichnis lege, muss ich die Dateierweiterung nicht angeben, um sie aufzurufen. Beispiel: echo notepad.exe% *> np.cmd Wenn ich dann einfach "np mytextfilename.txt" eingebe, wird der Editor angezeigt. Ich muss nicht "np.cmd" eingeben, um es aufzurufen.
Jon Davis
2
@ stimulpy77: Dies ist der Fall, wenn np.cmd die einzige Datei mit diesem Namen ist, aber "wenn zwei Dateien mit demselben Dateinamen und diesen beiden Erweiterungen vorhanden sind" , besteht die einzige Möglichkeit, die .cmd- Datei auszuführen, darin, ihre Erweiterung einzuschließen. ..
Aacini
1
Dies ist eine Notwendigkeit, Mehrdeutigkeiten für jede Shell aufzulösen, was nichts mit technischen Unterschieden zwischen .cmd und .bat zu tun hat. Dies liegt wahrscheinlich daran, dass filename.bat alphabetisch vor filename.cmd steht.
Jon Davis
6
Dies hängt tatsächlich von der PATHEXTUmgebungsvariablen ab. Die Reihenfolge, in der die Erweiterungen angezeigt werden, hat die Rangfolge, wenn keine Erweiterung angegeben ist. Erwähnenswert ist auch, dass es nicht erforderlich ist, eine Erweiterung für die Dateien anzugeben, deren Erweiterung in der env-Variablen angezeigt wird.
Ricardo Zorio
8

Alles, was in einem Stapel arbeitet, sollte in einem cmd funktionieren. cmd bietet einige Erweiterungen zur Steuerung der Umgebung. Außerdem wird cmd von einem neuen cmd-Interpreter ausgeführt und sollte daher schneller (bei kurzen Dateien nicht erkennbar) und stabiler sein, da bat unter der NTVDM-emulierten 16-Bit-Umgebung ausgeführt wird

Lorenzo Boccaccia
quelle
Sollte keinen Unterschied in der Geschwindigkeit machen. .batläuft nicht unter DOS in NT. Ein VDM wird nur gestartet, wenn ein Programm es benötigt, und wird unter 64-Bit-Windows nicht einmal unterstützt, obwohl ich glaube, dass .bat dies ist.
Gringo Suave
3

Die Ausführung von .cmd- und .bat-Dateien ist unterschiedlich, da sie sich in einer .cmd-Fehlerpegelvariablen für einen Befehl ändern kann, der von Befehlserweiterungen betroffen ist. Das ist es wirklich.

zask
quelle
Grob ^. ^ Es gibt Unterschiede in der jeweils verwendeten Befehlssprache (.bat-Dateien erhalten eine Kompatibilitätsversion). Einige davon können durch dieses Skript von hier veranschaulicht werden: @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
In .cmd-Dateien legt jeder Befehl die Fehlerstufe fest, in .bat-Dateien lassen einige Befehle die Fehlerstufe unverändert, wie in der akzeptierten Antwort beschrieben
jeb
1
BAT wurde für die Interaktion mit COMMAND.COM, dem Befehlsinterpreter von DOS, erstellt. Microsoft hat die meisten DOS-Befehle in seinen neuen Interpreter namens CMD übernommen. EXE. CMD wurde für die Schnittstelle mit CMD.EXE erstellt und unterbricht die Kompatibilität mit COMMAND.COM. hauptsächlich bekannt dafür, wie sie mit der Variablen errorlevel umgehen. Bei Verwendung von BAT wird diese Variable nur geändert, wenn ein tatsächlicher Fehler auftritt, und es tritt keine Statusänderung auf, wenn jeder Befehl erfolgreich ausgeführt wird. Dies gilt nicht für CMD, da die Variable auf Fehlerebene den Status auch dann ändern würde, wenn keine Fehler auftreten.
Zask
3

Ich glaube, wenn Sie den Wert der ComSpec-Umgebungsvariablen in %SystemRoot%system32\cmd.exe(CMD) ändern, spielt es keine Rolle, ob die Dateierweiterung .BAToder ist .CMD. Ich bin nicht sicher, aber dies kann sogar die Standardeinstellung für WinXP und höher sein.

Patrick Manschette
quelle
1

Etwas abseits des Themas, aber haben Sie Windows Scripting Host in Betracht gezogen ? Vielleicht finden Sie es schöner.

Marcin
quelle
13
In diesem Fall PowerShell, das WSH / cscript.exe ablehnt.
Jon Davis
3
@ stimulpy77 Stimmt, obwohl Powershell mir ziemlich schrecklich erscheint.
Marcin
2
Ich finde WSH viel schlimmer. Ich nehme an, es hängt alles davon ab, was wir für "schrecklich" messen. PowerShell hat eine grausame Startzeit. Alles daran ist absolut wunderbar IMO.
Jon Davis
Entschuldigen Sie die Formatierung, aber um die PSH-Startzeit zu beschleunigen, versuchen Sie Folgendes auszuführen: Set-Alias ​​ngen @ (dir (Join-Pfad $ {env: \ windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -descending lastwritetime) [0] .fullName [NEUE LINE HIER] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
mjbnz
1
Völlig außerhalb des Themas.
HappyDog
1

Die Erweiterung macht keinen Unterschied.

Es gibt geringfügige Unterschiede zwischen der COMMAND.COMBehandlung der Datei und CMD.EXE.

Waldo
quelle
-10

ein Unterschied:

.cmd-Dateien werden vor der Ausführung in den Speicher geladen. .bat-Dateien führen eine Zeile aus, lesen die nächste Zeile, führen diese Zeile aus ...

Sie können darauf stoßen, wenn Sie eine Skriptdatei ausführen und sie dann bearbeiten, bevor sie ausgeführt wird. Bat-Dateien werden dadurch durcheinander gebracht, Cmd-Dateien jedoch nicht.

grau
quelle
Wie bereits festgestellt, definiert die Variable ComSpec env, welches Programm gestartet wird. Wollen Sie damit im Wesentlichen sagen, dass command.com die Datei zeilenweise liest, während cmd.exe die Datei vorab in den Speicher lädt? Können Sie hierzu einen Hinweis geben?
Chris Noe
24
Es ist falsch für Vista und XP, beide Dateitypen werden Zeile für Zeile gelesen. Wenn Sie die .cmd- oder .bat-Datei
anhalten
1
Man könnte darüber diskutieren, ob es Zeile für Zeile ist, denn wenn Sie die Ausführung in der Mitte der Befehlsdatei anhalten und am Anfang ein Zeichen hinzufügen, wird der Parser bei Wiederaufnahme um ein Zeichen deaktiviert, wodurch möglicherweise der Rest Ihres Skripts entfernt wird.
2
Sie sollten nicht diskutieren .bat und .cmd unterscheiden sich nicht in dieser Weise. Beide werden immer zeilenweise gelesen. Sie können es testen, wenn Sie nicht glauben. Erstellen Sie eine Batch-Datei, die sie echo 1&pausedann ausgeführt hat. Du wirst sehen 1und Press any key to continue.... Fügen Sie im angehaltenen Zustand eine neue Zeile echo 2&pausemit dem externen Editor hinzu. Drücke eine Taste. Du wirst sehen 2und Press any key to continue.... Sie können sogar versuchen, echo 3&pauseam Anfang hinzuzufügen . Wenn Sie danach erneut eine Taste drücken, sehen Sie 2.
Venimus