Windowsbatch file:.bat vs .cmd?
据我了解, .bat
是旧的16位命名约定, .cmd
是32位Windows,即从NT开始。 但是我继续在任何地方看到.bat文件,而且他们似乎使用任一后缀完全相同。 假设我的代码永远都不需要运行在比NT更早的任何东西上,那么我的batch file是以什么方式命名的,或者是使用错误的后缀来等待我呢?
维基百科 :
来自维基百科的新报价
.cmd和.bat文件执行之间唯一已知的区别是在.cmd文件中,ERRORLEVELvariables即使在受命令扩展(启用命令扩展)影响的成功命令时也会更改,而在.bat文件中,ERRORLEVELvariables仅在错误时才会更改。
上面的维基百科报价的来源实际上是基于这个新闻组发布 。
就CMD.EXE而言.CMD和.BAT之间的区别是:启用了扩展,.CMD文件中的PATH / APPEND / PROMPT / SET / ASSOC将设置ERRORLEVEL而不pipe错误。 .BAT只在出错时设置ERRORLEVEL。
不仅比维基百科的文本有更多的限制,而且也值得明确提及,因为它是由Mark Zbikowski自己发布的 – 这给了IMHO巨大的可信度奖金。
以下是本主题中各种答案和引用参考文献的核实信息汇编:
-
command.com
是在MS-DOS中引入的16位命令处理器,也被用于Win9x系列操作系统。 -
cmd.exe
是Windows NT中的32位命令处理器(64位Windows操作系统也有一个64位版本)。cmd.exe
从来不是Windows 9x的一部分。 它起源于OS / 2版本1.0,并且OS / 2版本的cmd
开始于16位(但它仍然是一个完全成熟的保护模式程序,带有start
命令)。 Windows NT从OS / 2inheritance了cmd
,但是Windows NT的Win32版本是从32位开始的。 虽然OS / 2在1992年达到了32位,但它的cmd
仍然是一个16位的OS / 2 1.x程序。 -
ComSpec
envvariables定义由.bat
和.cmd
脚本启动的程序。 (从WinNT开始,这个默认是cmd.exe
。) -
cmd.exe
向后兼容command.com
。 - 为
cmd.exe
devise的脚本可命名为.cmd
以防止在Windows 9x上意外执行。 这个文件扩展名也可以追溯到OS / 2版本1.0和1987。
以下列出了command.com
不支持的cmd.exe
function:
- 长文件名(超过8.3格式)
- 命令历史
- Tab完成
- 转义字符:
^
(用于:\ & | > < ^
) - 目录堆栈:
PUSHD
/POPD
- 整数算术:
SET /A i+=1
- search/replace/子string:
SET %varname:expression%
- 命令replace:
FOR /F
(之前存在,已经增强) - 函数:
CALL :label
执行顺序:
如果脚本的两个.bat和.cmd版本(test.bat,test.cmd)位于同一个文件夹中,并且运行没有扩展名(testing)的脚本,默认情况下脚本的.bat版本将运行,甚至在64位Windows 7上执行的顺序由PATHEXT环境variables控制。 有关更多详细信息,请参阅命令提示符执行文件的顺序 。
参考文献:
- CMD.EXE
- command.com
维基百科: 命令shell的比较
这些答案有点太长,侧重于交互式使用。 重要的区别是:
-
.cmd
防止在非NT系统上无意的执行。 -
.cmd
使内置命令可以在成功时将Errorlevel更改为0。
编辑:在Windows 2000或更高版本下,命令扩展在默认情况下都处于.bat和.cmd文件中。
在2012年及以后,我推荐独家使用.cmd
。
不,这丝毫不重要。 在NT上.bat和.cmd扩展名都会导致cmd.exe处理器以完全相同的方式处理该文件。
有关来自MS TechNet的WinNT-class系统上的command.com与cmd.exe有关的其他有趣信息( http://technet.microsoft.com/zh-cn/library/cc723564.aspx ):
这种行为揭示了一个非常重要的Windows NT非常微妙的function。 Windows NT附带的16位MS-DOSshell(COMMAND.COM)是专门为Windows NTdevise的。 当一个命令被这个shell执行时,它并没有真正的执行它。 而是将命令文本打包并将其发送到32位CMD.EXE命令shell以供执行。 由于所有命令实际上都是由CMD.EXE(Windows NT命令shell)执行的,所以16位shellinheritance了完整的Windows NT shell的所有function和工具。
RE:显然,当command.com被调用是一个复杂的谜;
几个月前,在一个项目过程中,我们不得不弄清为什么一些我们想在CMD.EXE下运行的程序实际上是在COMMAND.COM下运行的。 有问题的“程序”是一个非常古老的.BAT文件,仍然每天运行。
我们发现batch file在COMMAND.COM下运行的原因是它是从.PIF文件(也是古老的)启动的。 由于只能通过PIF使用的特殊内存configuration设置已经变得无关紧要,我们用传统的桌面快捷方式replace了它。
从快捷方式启动的同一batch file在CMD.EXE中运行。 当你考虑一下,这是有道理的。 我们花了这么长时间才弄清楚的原因,部分原因是我们忘记了它在创业小组的项目是一个PIF,因为它自1998年以来一直在生产。
由于原帖是关于使用.bat或.cmd 后缀的后果,不一定是文件内部的命令…
.bat和.cmd之间的另外一个区别是,如果两个文件具有相同的文件名和这两个扩展名,则:
-
在命令行中input文件名或文件名 .bat将运行.bat文件
-
要运行.cmd文件,您必须input文件名 .cmd
不过,在Windows 7上,BAT文件也有这样的区别:如果你曾经在同一个目录中创buildTEST.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>
所有在批处理中工作的人都应该工作在一个cmd; cmd提供了一些扩展来控制环境。 而且,cmd是在新的cmd解释器中执行的,因此在NTVDM模拟的16位环境下应该更快(在短文件中不明显)并且更稳定
我相信,如果您将ComSpec环境variables的值更改为%SystemRoot%system32 \ cmd.exe,则文件扩展名是.BAT还是.CMD无关紧要。 我不确定,但这甚至可能是WinXP及更高版本的默认值。
稍微偏离主题,但你有没有考虑过Windows脚本宿主 ? 你可能会发现它更好。
扩展没有区别。 处理文件与CMD.EXE的COMMAND.COM之间略有不同
.cmd和.bat文件的执行方式不同,因为在.cmd错误级别variables中,它可以在受命令扩展影响的命令上更改。 这是真的。
以下是我发现的一个区别: .cmd
文件中需要 EnableDelayedExpansion
。
在.bat
文件的情况下,默认情况下是隐含的。 ( Windows 10 )
dir *? | find /i "FOOBAR" if ERRORLEVEL 0 ( set result="found" ) else ( set result="not found" ) echo %result%
这在.bat
起作用,但是在.cmd
文件的情况下总是被found
。
将line 2
更改为以下,使其按预期工作:
if %ERRORLEVEL% equ 0 (
最后为.cmd
文件这工作正常:
setLocal EnableDelayedExpansion ... if !ErrorLevel! equ 1 ( ...
作为一名Cmd程序员,并且遍布networking,你使用哪一个真的无关紧要,你可以在Windows 7上有一个.bat
程序,然后在Windows 10上运行它。但是如果你要它在Windows 10上可能无法运行Windows 7上的所有命令.cmd
完全相同,并运行完全相同的程序和代码。
所有不同之处在于,它是同一个程序的不同名称,只要它连接到CMD.EXE
,它就运行相同的命令。
区别:
.cmd文件在执行前被加载到内存中。 .bat文件执行一行,读取下一行,执行该行…
你可以在执行一个脚本文件时遇到这个问题,然后在执行完之前进行编辑。 蝙蝠文件将由此弄乱,但cmd文件不会。