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

Chr*_*Noe 715 windows cmd batch-file

据我所知,它.bat是旧的16位命名约定,.cmd适用于32位Windows,即从NT开始.但我继续在任何地方看到.bat文件,并且它们似乎使用任一后缀完全相同.假设我的代码将永远不需要对新台币任何旧的运行,是否真的重要走哪条路我名字我的批处理文件,还是有一些疑难杂症,通过使用错误的后缀等着我?

Ben*_*ein 431

这个新闻组记录马克·茨柏克沃斯基自己:

就CMD.EXE而言,.CMD和.BAT之间的区别在于:启用扩展后,.CMD文件中的PATH/APPEND/PROMPT/SET/ASSOC将设置ERRORLEVEL而不管错误..BAT仅在出错时设置ERRORLEVEL.

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

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

  • 我认为这意味着如果ERRORLEVEL设置为非0,那么您运行其中一个命令,它将在.bat文件中保持单独(非0),但在.cmd文件中重置为0.但是,Windows就是这样,很可能它实际上会导致一个无实体的声音告诉你,在Pig Latin中,"如果你非常在乎,请重置ERRORLEVEL!". (29认同)
  • 我认为只是说那些特定的命令会做不同的set/not set动作.其他人会像平常一样工作 (5认同)
  • 这是否意味着使用.bat脚本在成功时不会返回ERRORLEVEL 0值?如果这是真的,我从来没有注意到它. (4认同)
  • 仅当由“.cmd”脚本执行时,FTYPE 命令还会将 ERRORLEVEL 清除为 0。 (3认同)
  • 我现在知道了。我更新了我的要点。显然,它在调用 `set var=..` 语句时不会(重新)设置错误级别。这很奇怪,因为我认为这是预期的行为。双方都可以提出论据。我会坚持使用 .bat 文件。:-) (2认同)
  • 注 - APPEND 命令已替换为未记录的 DPATH 命令,尽管 `DPATH /?` 仍将该命令列为 APPEND。此外,该 Wiki 文章已被大部分更正,只是它没有列出 DPATH。 (2认同)

Chr*_*Noe 400

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

  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继承cmd自OS/2,但Windows NT的Win32版本从32位开始.虽然OS/2在1992年变为32位,但它cmd仍然是一个16位OS/2 1.x程序.
  3. ComSpec环境变量定义了程序由发射.bat.cmd脚本.(从WinNT开始,默认为cmd.exe.)
  4. cmd.exe向后兼容command.com.
  5. cmd.exe可以命名专为此目的设置的脚本,.cmd以防止在Windows 9x上意外执行.此文件扩展名也可以追溯到OS/2版本1.0和1987.

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

  • 长文件名(超过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环境变量控制.有关更多详细信息,请参阅命令提示符执行文件的顺序.

参考文献:

维基百科:命令shell的比较

  • 我相信cmd.exe是用NT 4.0引入的,而不是Windows 95. (6认同)
  • 几个小问题:1).bat不一定会调用command.com - 显然当调用command.com时有点复杂; 2)command.com是用MS-DOS引入的; 3)cmd.exe可以运行大多数command.com脚本,但有一些小的command.com东西在cmd中不起作用. (4认同)
  • 别名和历史记录是控制台窗口(conhost.exe 或 csrss.exe)的功能,而不是 cmd.exe 的功能。历史记录与F7弹出框集成。每个附加程序都有自己的历史记录和别名,由 [console API](http://msdn.microsoft.com/en-us/library/ms682073) 或通过 [doskey](http:// technet.microsoft.com/en-us/library/bb490894.aspx)。 (3认同)
  • 克里斯:请参阅维基百科文章的当前版本,尤其是。Mark Zbikowski 在 http://groups.google.com/group/microsoft.public.win2000.cmdprompt.admin/msg/ad9066638815812c 上的评论 (2认同)
  • 只是添加一些关于此事的信息:`dir filename`与command.com中的`dir filename.*`相同; cmd.exe中需要使用通配符.在command.com`rem创建一个空文件> empty.txt`有效; 不在cmd.exe中. (2认同)
  • 似乎只有一点点与OP的问题有关,OP的问题与.bat和.cmd之间的差异有关,而与command.com和cmd.exe之间的差异无关。在我阅读本文时,问题是关于.bat文件和.cmd文件之间的区别,其他所有条件都相同。 (2认同)
  • `^` 可以转义的字符列表是错误的,`\` 无法转义:可以转义以下特殊字符:`&amp;`、`|`、`&gt;`、`&lt;`、`^` , `"`, `(`, `)`; 然后你还可以转义标记分隔符,如 _space_, _tab_, `,`, `;`, `=`; 当有两个换行符时,你甚至可以转义换行符连续的换行符;当启用延迟扩展时,您甚至可以转义“!”... (2认同)

Gri*_*ave 72

这些答案有点太长,专注于交互式使用.脚本的重要区别是:

  • .cmd 防止在非NT系统上无意中执行.
  • .cmd 启用内置命令,在成功时将Errorlevel更改为0.

默认情况下,Windows 2000或更高版本下的.bat和.cmd文件中都启用了命令扩展.

在2012年及以后,我建议.cmd专门使用.

  • 国际海事组织,这是重点.当您想要确保它们不会在较旧的16位操作系统上被执行时,或者如果您不确定它们是否可行时,可以使用.cmd作为较新脚本的扩展名. (7认同)
  • 我真的很感激简洁,务实和清晰的答案,无数的大学课堂般的答案. (6认同)
  • 我是大学教授,我同意@Liquid Core!简洁,务实,清晰的答案是我们学习的方式(当我们尚不了解时)。然后,以某种方式,一旦我们理解了它,便感到有一种以抽象和难以理解的方式来解释它的冲动。奇怪的。好观察! (2认同)

Mic*_*urr 25

不 - 丝毫没关系.在NT上,.bat和.cmd扩展名都会导致cmd.exe处理器以完全相同的方式处理文件.

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

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

  • 这可能很重要; 正如您的链接文字所提到的那样,差异是微妙的. (5认同)

小智 16

RE:显然当调用command.com时有点复杂的谜团;

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

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

从快捷方式启动的同一批处理文件在CMD.EXE中运行.当你考虑它时,这是有道理的.我们花了这么长时间才弄明白的原因部分是由于我们忘记了它在启动组中的项目是PIF,因为它自1998年以来一直在生产.

  • 这是什么操作系统?XP之前的东西? (2认同)

tvC*_*vCa 14

尽管如此,在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 bat
bat

C:\Temp>
Run Code Online (Sandbox Code Playgroud)

  • @David:不对.发生这种情况是因为在`PATHEXT`变量中.BAT扩展名放在.CMD之前(如本答案所示).如果在PATHEXT中修改此顺序,则将执行test.cmd. (24认同)
  • 还值得注意的是,当前目录在 `PATH` 环境变量中位于其他目录之前,无论扩展名如何。 (4认同)

Rob*_*com 13

由于原来的文章是关于使用.bat或.cmd的后果后缀,不一定是命令里面的文件...

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

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

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

  • 它实际上取决于`PATHEXT`环境变量.如果未指定扩展名,则扩展名出现的顺序是优先顺序.还值得一提的是,没有必要为其扩展名出现在env变量中的文件指定扩展名. (6认同)
  • 嗯?如果我在我的目录中放置一个cmd文件,我不必指定文件扩展名来调用它.示例:echo notepad.exe%*> np.cmd然后,如果我只输入"np mytextfilename.txt",它将显示记事本.我不必输入"np.cmd"来调用它. (2认同)
  • @ stimpy77:如果np.cmd是唯一具有该名称的文件,则为true,但_"如果两个文件存在同一文件名且两个扩展名都为_",那么执行.cmd的唯一方法是包含它延期... (2认同)
  • 这是解决任何 shell 歧义的必要条件,与 .cmd 与 .bat 之间的技术差异无关。这可能是因为 filename.bat 按字母顺序位于 filename.cmd 之前。 (2认同)

Lor*_*cia 8

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