据我了解,.bat
是旧的 16 位命名约定,而 .cmd
用于 32 位 Windows,即以 NT 开头。但是我继续在各处看到 .bat 文件,并且使用任一后缀它们的工作方式似乎完全相同。假设我的代码永远不需要在 NT 之前的任何东西上运行,那么我命名批处理文件的方式真的很重要,还是有一些 gotcha 使用错误的后缀在等待我?
来自 Mark Zbikowski 本人的 this news group posting:
就 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 从 OS/2 继承了 cmd,但 Windows NT 的 Win32 版本从 32 位开始。虽然 OS/2 在 1992 年变成了 32 位,但它的 cmd 仍然是一个 16 位的 OS/2 1.x 程序。 ComSpec env 变量定义了由 .bat 和 .cmd 脚本启动的程序。 (从 WinNT 开始,默认为 cmd.exe。) cmd.exe 向后兼容 command.com。为 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(以前存在,已增强)
功能:调用:标签
执行顺序:
如果脚本(test.bat、test.cmd)的 .bat 和 .cmd 版本都在同一个文件夹中,并且您在没有扩展名的情况下运行脚本(test),则默认情况下,脚本的 .bat 版本将运行,即使在 64 位 Windows 7 上。执行顺序由 PATHEXT 环境变量控制。有关详细信息,请参阅 Order in which Command Prompt executes files。
参考:
命令文件
命令网
维基百科:Comparison of command shells
dir filename
与 command.com 中的 dir filename.*
相同; cmd.exe 中需要通配符。在 command.com rem Create an empty file > empty.txt
有效;不在 cmd.exe 中。
这些答案有点太长了,而且侧重于交互使用。脚本的重要区别是:
.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 外壳的所有功能和功能。
command /c ver
与启动 command.com 并键入 ver。
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>
PATHEXT
变量中 .BAT 扩展名放在 .CMD 之前(如本答案所示)。如果您在 PATHEXT 中修改此顺序,将改为执行 test.cmd。
PATH
环境变量中的其他目录之前。
由于原始帖子是关于使用 .bat 或 .cmd 后缀的后果,不一定是文件中的命令......
.bat 和 .cmd 之间的另一个区别是,如果存在具有相同文件名和扩展名的两个文件,则:
在命令行输入 filename 或 filename.bat 将运行 .bat 文件
要运行 .cmd 文件,您必须输入 filename.cmd
PATHEXT
环境变量。如果未指定扩展名,则扩展名出现的顺序是优先顺序。还值得一提的是,没有必要为文件指定扩展名,其扩展名出现在 env 变量中。
.cmd
来运行 MyScript.cmd
- AFAIK C:\> MyScript
工作正常(对于 .cmd
或 {5 } 个文件)。
批处理中的所有工作都应该在 cmd 中工作; cmd 提供了一些用于控制环境的扩展。此外,cmd 由新的 cmd 解释器执行,因此随着 bat 在 NTVDM 模拟 16 位环境下运行,它应该更快(在短文件上不明显)和更稳定
.bat
在 NT 的 DOS 下不运行。 VDM 仅在程序需要时才启动,并且在 64 位 Windows 中甚至不支持,尽管我相信 .bat 是。
.cmd 和 .bat 文件执行是不同的,因为在 .cmd 错误级别变量中,它可以在受命令扩展影响的命令上更改。就是这样。
@echo off&setlocal ENABLEEXTENSIONS call :func&&echo/I'm a cmd||echo/I'm a bat goto :EOF :func md;2>nul set var=1
我相信如果您将 ComSpec 环境变量的值更改为 %SystemRoot%system32\cmd.exe
(CMD),那么文件扩展名是 .BAT
还是 .CMD
都没有关系。我不确定,但这甚至可能是 WinXP 及更高版本的默认设置。
扩展没有区别。
COMMAND.COM
处理文件与 CMD.EXE
之间存在细微差别。
区别:
.cmd 文件在执行之前被加载到内存中。 .bat 文件执行一行,读取下一行,执行该行...
您可以在执行脚本文件时遇到此问题,然后在执行完成之前对其进行编辑。 bat 文件会因此而混乱,但 cmd 文件不会。
.btm
("batch to memory") files as employed with JP Software's replacement command interpreters。
echo 1&pause
的批处理文件,然后执行它。您将看到 1
和 Press any key to continue...
。暂停时使用外部编辑器添加新行 echo 2&pause
。按一个键。您将看到 2
和 Press any key to continue...
。您甚至可以尝试在开头添加 echo 3&pause
。当您再次按下某个键时,您将看到 2
。
不定期副业成功案例分享
DPATH /?
仍将该命令列为 APPEND。此外,该 Wiki 文章此后大部分已得到更正,但未列出 DPATH。.cmd
脚本执行时将 ERRORLEVEL 清除为 0。