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巨大的可信度奖金。

以下是本主题中各种答案和引用参考文献的核实信息汇编:

  1. command.com是在MS-DOS中引入的16位命令处理器,也被用于Win9x系列操作系统。
  2. 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程序。
  3. ComSpec envvariables定义由.bat.cmd脚本启动的程序。 (从WinNT开始,这个默认是cmd.exe 。)
  4. cmd.exe向后兼容command.com
  5. cmd.exedevise的脚本可命名为.cmd以防止在Windows 9x上意外执行。 这个文件扩展名也可以追溯到OS / 2版本1.0和1987。

以下列出了command.com不支持的cmd.exefunction:

  • 长文件名(超过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文件不会。