Windows批处理文件:. bat vs. cmd?

据我所知,.bat是旧的16位命名约定,.cmd适用于32位Windows,即以NT开头。但是我继续在任何地方看到. bat文件,它们似乎使用任何后缀都完全相同。假设我的代码永远不需要在比NT更早的东西上运行,我以何种方式命名批处理文件真的很重要吗,还是有一些明白了使用错误的后缀等待我?

531398 次浏览

不-这一点也不重要。在NT上,. bat和. cmd扩展名都导致cmd.exe处理器以完全相同的方式处理文件。

来自MS TechNet(http://technet.microsoft.com/en-us/library/cc723564.aspx)的有关WinNT级系统上command.com与cmd.exe的其他有趣信息:

这种行为揭示了一个非常微妙的Windows NT的功能非常重要。16位MS-DOS外壳(COMMAND.COM)附带WindowsNT是专门为Windows设计的NT。当输入命令时由这个shell执行,它不实际执行它。相反,它打包命令文本并发送它到32位CMD.EXE命令shell执行。因为所有命令都是实际由CMD.EXE(theWindows NT命令shell),16位shell继承了所有功能和完整Windows NT的设施shell。

这个新闻组发帖mark zbikowski自己:

. CMD和. BAT之间的区别就CMD.EXE而言是:启用扩展后,PATH/APPEND/PROMPT/SET/ASSOC in. CMD文件将设置ERRORLEVEL而不管错误。. BAT设置ERRORLEVEL#36825;的错误

换句话说,如果ERRORLEVEL设置为非0,然后运行其中一个命令,则结果ERRORLEVEL将为:

  • 在. bat文件中单独保留其非0值
  • 在. cmd文件中重置为0。

扩展没有区别。

COMMAND.COM处理文件与CMD.EXE之间存在细微差异。

在批处理中工作的所有内容都应该在cmd中工作;cmd提供了一些用于控制环境的扩展。此外,cmd由新的cmd解释器执行,因此应该更快(在短文件上不明显)并且更稳定,因为bat在NTVDM模拟的16位环境下运行

我相信如果您将ComSpec环境变量的值更改为%SystemRoot%system32\cmd.exe(CMD),那么文件扩展名是.BAT还是.CMD并不重要。我不确定,但这甚至可能是WinXP及更高版本的默认值。

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

  1. command.com是MS-DOS中引入的16位命令处理器,也用于Win9x系列操作系统。
  2. cmd.exe是Windows NT中的32位命令处理器(64位Windows操作系统也有64位版本)。cmd.exe从来不是Windows 9x的一部分。它起源于OS/2版本1.0,而cmd的OS/2版本始于16位(但仍然是一个完全成熟的保护模式程序,使用类似start的命令)。Windows NT继承了OS/2的cmd,但Windows NT的Win32版本始于32位。尽管OS/2在1992年变成了32位,但它的cmd仍然是一个16位OS/2 1. x程序。
  3. ComSpec env变量定义了.bat.cmd脚本启动的程序。(从WinNT开始,默认为cmd.exe。)
  4. cmd.exe向下兼容command.com
  5. cmd.exe设计的脚本可以命名为.cmd,以防止在Windows 9x上意外执行。此文件扩展名也可以追溯到OS/2版本1.0和1987年。

以下是command.com不支持的cmd.exe功能列表:

  • 长文件名(超过8.3格式)
  • 命令历史
  • 选项卡补全
  • 转义字符:^(用于:\ & | > < ^
  • 目录栈:PUSHD/POPD
  • 整数算术:SET /A i+=1
  • 搜索/替换/子字符串:SET %varname:expression%
  • 命令替换:FOR /F(以前存在,已增强)
  • 功能:CALL :label

执行顺序:

如果脚本的. bat和. cmd版本(test.bat、test.cmd)都在同一个文件夹中,并且您在没有扩展名(test)的情况下运行脚本,则默认情况下脚本的. bat版本将运行,即使在64位Windows 7上也是如此。执行顺序由PATHEXT环境变量控制。有关更多详细信息,请参阅命令提示符执行文件的顺序

参考文献:

wikipedia:命令shell的比较

区别:

. cmd文件在执行之前被加载到内存中。. bat文件执行一行,读取下一行,执行该行…

当您执行脚本文件时,您可能会遇到这种情况,然后在执行完成之前对其进行编辑。bat文件将被此弄乱,但cmd文件不会。

回复:显然,何时调用command.com有点复杂;

几个月前,在一个项目的过程中,我们必须弄清楚为什么我们想要在CMD.EXE下运行的一些程序实际上在COMMAND.COM.这个“程序”是一个非常古老的. BAT文件,仍然每天运行。

我们发现批处理文件在COMMAND.COM下运行的原因是它是从. PIF文件(也是古老的)启动的。由于仅通过PIF可用的特殊内存配置设置变得无关紧要,我们用传统的桌面快捷方式替换了它。

从快捷方式启动的同一个批处理文件在CMD.EXE.中运行。仔细想想,这是有道理的。我们花了这么长时间才弄清楚,部分原因是我们忘记了它在启动组中的项目是PIF,因为它从1998年开始生产。

这些答案有点太长,集中在交互式使用上。脚本的重要区别是:

  • .cmd防止在非NT系统上意外执行。
  • .cmd使内置命令能够在成功时将错误级别更改为0。

没那么刺激吧?

以前在.cmd文件中启用了许多附加功能,称为命令扩展。但是,现在默认情况下,Windows 2000及更高版本下的.bat.cmd文件都启用了它们。

底线:在2012年及以后,我建议只使用.cmd

由于最初的帖子是关于使用. bat或. cmd后缀的后果,不一定是命令里面文件…

. bat和. cmd之间的另一个区别是,如果存在两个具有相同文件名和这两个扩展名的文件,那么:

  • 在命令行输入filenamefilename. bat将运行. bat文件

  • 要运行. cmd文件,您必须输入filename. cmd

尽管如此,在Windows 7上,BAT文件也有这种区别:如果您在同一目录中TEST.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 batbat
C:\Temp>

. cmd和. bat文件执行是不同的,因为在. cmd错误级别变量中,它可以在受命令扩展名影响的命令上进行更改。就是这样。