据我了解,.bat
是旧的 16 位命名约定,.cmd
适用于 32 位 Windows,即以 NT 开头。但是我继续在各处看到 .bat 文件,并且使用任一后缀它们的工作方式似乎完全相同。假设我的代码永远不需要在任何比 NT 更旧的东西上运行,那么我命名批处理文件的方式真的很重要,还是使用错误的后缀有一些问题在等着我?
12 回答
来自Mark Zbikowski本人发布的这个新闻组:
就 CMD.EXE 而言,.CMD 和 .BAT 之间的区别在于: 启用扩展后,.CMD 文件中的 PATH/APPEND/PROMPT/SET/ASSOC 将设置 ERRORLEVEL 而不管错误。.BAT 仅在错误时设置 ERRORLEVEL。
换句话说,如果 ERRORLEVEL 设置为非 0,然后您运行这些命令之一,则生成的 ERRORLEVEL 将是:
- 在 .bat 文件中保持其非 0 值
- 在 .cmd 文件中重置为 0。
以下是来自该线程中各种答案和引用的参考文献的经过验证的信息的汇编:
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 继承cmd
自 OS/2,但 Windows NT 的 Win32 版本从 32 位开始。尽管 OS/2 在 1992 年变成了 32 位,但它cmd
仍然是一个 16 位的 OS/2 1.x 程序。- env 变量定义了
ComSpec
由脚本启动的程序。(从 WinNT 开始,默认为.).bat
.cmd
cmd.exe
cmd.exe
向后兼容command.com
.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
执行顺序:
如果脚本(test.bat、test.cmd)的 .bat 和 .cmd 版本都在同一个文件夹中,并且您在没有扩展名的情况下运行脚本(test),则默认情况下,脚本的 .bat 版本将运行,即使在 64 位 Windows 7 上。执行顺序由 PATHEXT 环境变量控制。有关详细信息,请参阅命令提示符执行文件的顺序。
参考:
维基百科:命令外壳的比较
这些答案有点太长了,而且侧重于交互使用。脚本的重要区别是:
.cmd
防止在非 NT 系统上无意执行。.cmd
启用内置命令以在成功时将 Errorlevel 更改为 0。
不是那么令人兴奋,是吗?
过去在.cmd
文件中启用了许多附加功能,称为命令扩展。但是,现在默认情况下对Windows 2000 和更高版本下的文件.bat
启用它们。.cmd
底线:在 2012 年及以后,我建议.cmd
只使用。
不——一点也不重要。在 NT 上,.bat 和 .cmd 扩展名都导致 cmd.exe 处理器以完全相同的方式处理文件。
有关来自 MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx )的 WinNT 类系统上 command.com 与 cmd.exe 的其他有趣信息:
这种行为揭示了 Windows NT 非常重要的一个非常微妙的特性。Windows NT 附带的 16 位 MS-DOS 外壳 (COMMAND.COM) 是专门为 Windows NT 设计的。当这个 shell 输入一个命令来执行时,它实际上并没有执行它。相反,它会打包命令文本并将其发送到 32 位 CMD.EXE 命令外壳以执行。因为所有命令实际上都由 CMD.EXE(Windows NT 命令外壳)执行,所以 16 位外壳继承了完整 Windows NT 外壳的所有功能和功能。
RE:显然,何时调用 command.com 有点复杂。
几个月前,在一个项目的过程中,我们不得不弄清楚为什么我们想在 CMD.EXE 下运行的一些程序实际上是在 COMMAND.COM 下运行的。有问题的“程序”是一个非常古老的 .BAT 文件,仍然每天运行。
我们发现批处理文件在 COMMAND.COM 下运行的原因是它是从 .PIF 文件(也很古老)启动的。由于只能通过 PIF 获得的特殊内存配置设置已变得无关紧要,因此我们将其替换为传统的桌面快捷方式。
从快捷方式启动的同一个批处理文件在 CMD.EXE 中运行。当您考虑它时,这是有道理的。我们花了这么长时间才弄明白的部分原因是我们忘记了它在启动组中的项目是 PIF,因为它从 1998 年就开始生产了。
尽管如此,在 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>
由于原始帖子是关于使用 .bat 或 .cmd后缀的后果,因此不一定是文件中的命令......
.bat 和 .cmd 之间的另一个区别是,如果存在具有相同文件名和扩展名的两个文件,则:
在命令行输入文件名或文件名.bat 将运行 .bat 文件
要运行 .cmd 文件,您必须输入文件名.cmd
批处理中的所有工作都应该在 cmd 中工作;cmd 提供了一些用于控制环境的扩展。此外,cmd 由新的 cmd 解释器执行,因此随着 bat 在 NTVDM 模拟 16 位环境下运行,它应该更快(在短文件上不明显)和更稳定
我相信,如果您将 ComSpec 环境变量的值更改为%SystemRoot%system32\cmd.exe
(CMD),那么文件扩展名是.BAT
还是.CMD
. 我不确定,但这甚至可能是 WinXP 及更高版本的默认设置。
.cmd 和 .bat 文件执行是不同的,因为在 .cmd 错误级别变量中,它可以在受命令扩展影响的命令上更改。就是这样。
扩展没有区别。
COMMAND.COM
处理文件与处理CMD.EXE
.
区别:
.cmd 文件在执行之前被加载到内存中。.bat 文件执行一行,读取下一行,执行该行...
您可以在执行脚本文件时遇到此问题,然后在执行完成之前对其进行编辑。bat 文件会因此而混乱,但 cmd 文件不会。