As I understand it, .bat
is the old 16-bit naming convention, and .cmd
is for 32-bit Windows, i.e., starting with NT. But I continue to see .bat files everywhere, and they seem to work exactly the same using either suffix. Assuming that my code will never need to run on anything older than NT, does it really matter which way I name my batch files, or is there some gotcha awaiting me by using the wrong suffix?
From this news group posting by Mark Zbikowski himself:
The differences between .CMD and .BAT as far as CMD.EXE is concerned are: With extensions enabled, PATH/APPEND/PROMPT/SET/ASSOC in .CMD files will set ERRORLEVEL regardless of error. .BAT sets ERRORLEVEL only on errors.
In other words, if ERRORLEVEL is set to non-0 and then you run one of those commands, the resulting ERRORLEVEL will be:
- left alone at its non-0 value in a .bat file
- reset to 0 in a .cmd file.
dir c:\doesntexist
, then execute a command that returns a success, such as dir "%temp%
- the errorlevel is set appropriately.. See this: gist.github.com/kodybrown/7430acd13634c682ae75. I just tested this on Windows 10, but I've done this in 7/8/8.1 and I'm pretty certain that it worked on XP as well. (No idea if it worked on Vista! Who used that anyway!?) –
Andrel set var=..
statement. Which is odd, because I assumed that was expected behavior. Arguments could be made for both. I'll stick with .bat files. :-) –
Andrel DPATH /?
still lists the command as APPEND. Also, the Wiki article has since been mostly corrected, except it does not list DPATH. –
Eubanks .cmd
script. –
Eubanks .cmd
file would get fed to command.com
rather than cmd.exe
, since presumably DOS doesn't search for them (by default) and Windows 9x doesn't have an association for them. The take-home being that you could justify skipping any "is this cmd.exe?" checks in .cmd
, but not in .bat
. (32-bit Windows still ships with the DOS compatibility, right?) –
Electrolyte Here is a compilation of verified information from the various answers and cited references in this thread:
command.com
is the 16-bit command processor introduced in MS-DOS and was also used in the Win9x series of operating systems.cmd.exe
is the 32-bit command processor in Windows NT (64-bit Windows OSes also have a 64-bit version).cmd.exe
was never part of Windows 9x. It originated in OS/2 version 1.0, and the OS/2 version ofcmd
began 16-bit (but was nonetheless a fully fledged protected mode program with commands likestart
). Windows NT inheritedcmd
from OS/2, but Windows NT's Win32 version started off 32-bit. Although OS/2 went 32-bit in 1992, itscmd
remained a 16-bit OS/2 1.x program.- The
ComSpec
env variable defines which program is launched by.bat
and.cmd
scripts. (Starting with WinNT this defaults tocmd.exe
.) cmd.exe
is backward compatible withcommand.com
.- A script that is designed for
cmd.exe
can be named.cmd
to prevent accidental execution on Windows 9x. This filename extension also dates back to OS/2 version 1.0 and 1987.
Here is a list of cmd.exe
features that are not supported by command.com
:
- Long filenames (exceeding the 8.3 format)
- Command history
- Tab completion
- Escape character:
^
(Use for:\ & | > < ^
) - Directory stack:
PUSHD
/POPD
- Integer arithmetic:
SET /A i+=1
- Search/Replace/Substring:
SET %varname:expression%
- Command substitution:
FOR /F
(existed before, has been enhanced) - Functions:
CALL :label
Order of Execution:
If both .bat and .cmd versions of a script (test.bat, test.cmd) are in the same folder and you run the script without the extension (test), by default the .bat version of the script will run, even on 64-bit Windows 7. The order of execution is controlled by the PATHEXT environment variable. See Order in which Command Prompt executes files for more details.
References:
wikipedia: Comparison of command shells
cmd
, and the new convention of .cmd
as an extension for command script files specifically for cmd
and not command
, was introduced with OS/2 version 1.0 in 1987. –
Scandura CD ..\..\..
(would move up 3 levels)? –
Comeon dir filename
is the same as dir filename.*
in command.com; the wild-card is required in cmd.exe. In command.com rem Create an empty file > empty.txt
works; not in cmd.exe. –
Vasyuta rem
also works in cmd
, but only like this: rem/>empty.txt
(instead of /
, the following characters can be used well: . \ : + [ ]
; note that ( )
do not work); –
Enright ^
is wrong, a \
cannot be escaped: the following special characters can be escaped: &
, |
, >
, <
, ^
, "
, (
, )
; then you can also escape token separators like space, tab, ,
, ;
, =
; you can even escape a line-feed character when there are two consecutive line-breaks; and you can even escape the !
when delayed expansion is enabled... –
Enright These answers are a bit too long and focused on interactive use. The important differences for scripting are:
.cmd
prevents inadvertent execution on non-NT systems..cmd
enables built-in commands to change Errorlevel to 0 on success.
Not that exciting, eh?
There used to be a number of additional features enabled in .cmd
files, called Command Extensions. However, they are now enabled by default for both .bat
and .cmd
files under Windows 2000 and later.
Bottom line: in 2012 and beyond, I recommend using .cmd
exclusively.
No - it doesn't matter in the slightest. On NT the .bat and .cmd extension both cause the cmd.exe processor to process the file in exactly the same way.
Additional interesting information about command.com vs. cmd.exe on WinNT-class systems from MS TechNet (http://technet.microsoft.com/en-us/library/cc723564.aspx):
This behavior reveals a quite subtle feature of Windows NT that is very important. The 16-bit MS-DOS shell (COMMAND.COM) that ships with Windows NT is specially designed for Windows NT. When a command is entered for execution by this shell, it does not actually execute it. Instead, it packages the command text and sends it to a 32-bit CMD.EXE command shell for execution. Because all commands are actually executed by CMD.EXE (the Windows NT command shell), the 16-bit shell inherits all the features and facilities of the full Windows NT shell.
command /c ver
versus starting command.com and typing ver. –
Hellen RE: Apparently when command.com is invoked is a bit of a complex mystery;
Several months ago, during the course of a project, we had to figure out why some programs that we wanted to run under CMD.EXE were, in fact, running under COMMAND.COM. The "program" in question was a very old .BAT file, that still runs daily.
We discovered that the reason the batch file ran under COMMAND.COM is that it was being started from a .PIF file (also ancient). Since the special memory configuration settings available only through a PIF have become irrelevant, we replaced it with a conventional desktop shortcut.
The same batch file, launched from the shortcut, runs in CMD.EXE. When you think about it, this makes sense. The reason that it took us so long to figure it out was partially due to the fact that we had forgotten that its item in the startup group was a PIF, because it had been in production since 1998.
Still, on Windows 7, BAT files have also this difference : If you ever create files TEST.BAT and TEST.CMD in the same directory, and you run TEST in that directory, it'll run the BAT file.
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>
PATHEXT
variable the .BAT extension is placed before .CMD one (as shown in this answer). If you modify this order in PATHEXT, the test.cmd would be executed instead. –
Vasyuta PATH
environment variable regardless of extension. –
Azalea Since the original post was regarding the consequences of using the .bat or .cmd suffix, not necessarily the commands inside the file...
One other difference between .bat and .cmd is that if two files exist with the same file name and both those extensions, then:
entering filename or filename.bat at the command line will run the .bat file
to run the .cmd file, you have to enter filename.cmd
PATHEXT
environment variable. The order in wich the extensions appears there is the order of precedence if an extension is not specified. It is also worth mentioning that it's not necessary to specify an extension for the files wich its extension appears in the env variable. –
Tapetum .cmd
in order to run MyScript.cmd
- AFAIK C:\> MyScript
works fine (for .cmd
or .bat
files). –
Dorothydorp everything working in a batch should work in a cmd; cmd provides some extensions for controlling the environment. also, cmd is executed by in new cmd interpreter and thus should be faster (not noticeable on short files) and stabler as bat runs under the NTVDM emulated 16bit environment
.bat
doesn't run under DOS in NT. A VDM is only started if a program needs it, and isn't even supported in 64bit Windows, though I believe .bat is. –
Sprawl I believe if you change the value of the ComSpec environment variable to %SystemRoot%system32\cmd.exe
(CMD) then it doesn't matter if the file extension is .BAT
or .CMD
. I'm not sure, but this may even be the default for WinXP and above.
.cmd and .bat file execution is different because in a .cmd errorlevel variable it can change on a command that is affected by command extensions. That's about it really.
@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
–
Velum The extension makes no difference.
There are slight differences between COMMAND.COM
handling the file vs CMD.EXE
.
a difference:
.cmd files are loaded into memory before being executed. .bat files execute a line, read the next line, execute that line...
you can come across this when you execute a script file and then edit it before it's done executing. bat files will be messed up by this, but cmd files won't.
.btm
("batch to memory") files as employed with JP Software's replacement command interpreters. –
Scandura echo 1&pause
then execute it. You will see 1
and Press any key to continue...
. While paused add a new line echo 2&pause
with external editor. Press a key. You will see 2
and Press any key to continue...
. You can even try adding echo 3&pause
in the beginning. When you press a key after that again you will see 2
. –
Leventis ( ... )
In that particular case it keep reading the code lines until the closing brace )
even if the code execution inside braces block is paused by the pause
command. To test that you can run Process Monitor
and setup the filter for Operation: ReadFile
+ Process Name: cmd.exe
. It keeps call ReadFile
after the pause command and until the last closing brace )
. At least it has the same behavior for .bat
and .cmd
on Windows 8. –
Adelric © 2022 - 2024 — McMap. All rights reserved.