据我了解, .bat 是旧的16位命名约定, .cmd 是32位Windows,即从NT开始 . 但我继续在任何地方看到.bat文件,并且它们似乎使用任一后缀完全相同 . 假设我的代码永远不需要在比NT更早的版本上运行,那么我命名我的批处理文件的方式真的很重要,或者是否有一些 gotcha 等待我使用错误的后缀?
.bat
.cmd
来自this news group posting自Mark Zbikowski:
就CMD.EXE而言, . CMD和.BAT之间的区别在于:启用扩展后,.CMD文件中的PATH / APPEND / PROMPT / SET / ASSOC将设置ERRORLEVEL而不管错误 . .BAT仅在出错时设置ERRORLEVEL .
换句话说,如果将ERRORLEVEL设置为非0然后运行其中一个命令,则生成的ERRORLEVEL将为:
单独留在.bat文件中的非0值
在.cmd文件中重置为0 .
由于原帖是关于使用.bat或.cmd后缀的后果,不一定是文件中的命令...
.bat和.cmd之间的另一个区别是,如果两个文件存在相同的文件名和两个扩展名,那么:
在命令行输入filename或filename.bat将运行.bat文件
要运行.cmd文件,您必须输入filename.cmd
批处理中的所有工作都应该在cmd中工作; cmd提供了一些控制环境的扩展 . 此外,cmd由新的cmd解释器执行,因此应该更快(在短文件上不明显)并且在NTVDM仿真16位环境下运行时更稳定
稍微偏离主题,但你考虑过Windows Scripting Host?你可能会发现它更好 .
作为一名Cmd程序员,并且在整个网络上看,你使用哪一个并不重要,你可以在Windows 7上运行 .bat 程序,并在Windows 10上运行它 . 但是如果你想要它在Windows 10上,您可能无法在Windows 7上运行所有命令 . .cmd 的方式完全相同,并运行完全相同的程序和代码 .
所有不同之处在于,它是同一程序的不同名称,只要它连接到 CMD.EXE ,它就会运行相同的命令 .
CMD.EXE
这是我发现的一个区别: EnableDelayedExpansion 在 .cmd 文件中是 required .在 .bat 文件的情况下,默认情况下它是隐式的 . (Windows 10)
EnableDelayedExpansion
dir *? | find /i "FOOBAR" if ERRORLEVEL 0 ( set result="found" ) else ( set result="not found" ) echo %result%
这适用于 .bat 但在 .cmd 文件的情况下始终为 found .将 line 2 更改为以下内容使其按预期工作:
found
line 2
if %ERRORLEVEL% equ 0 (
最后,对于 .cmd 文件,这可以正常工作:
setLocal EnableDelayedExpansion ... if !ErrorLevel! equ 1 ( ...
以下是本主题中各种答案和引用参考文献的经过验证的信息汇编:
command.com 是MS-DOS中引入的16位命令处理器,也用于Win9x系列操作系统 .
command.com
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程序 .
cmd.exe
cmd
start
ComSpec env变量定义 .bat 和 .cmd 脚本启动的程序 . (从WinNT开始,默认为 cmd.exe . )
ComSpec
cmd.exe 向后兼容 command.com .
为 cmd.exe 设计的脚本可以命名为 .cmd ,以防止在Windows 9x上意外执行 . 此文件扩展名也可以追溯到OS / 2版本1.0和1987 .
以下是 command.com 不支持的 cmd.exe 功能列表:
长文件名(超过8.3格式)
命令历史记录
标签完成
逃脱角色: ^ (用于: \ & | > < ^ )
^
\ & | > < ^
目录堆栈: PUSHD / POPD
PUSHD
POPD
整数运算: SET /A i+=1
SET /A i+=1
搜索/替换/子串: SET %varname:expression%
SET %varname:expression%
命令替换: FOR /F (之前存在,已被增强)
FOR /F
功能: CALL :label
CALL :label
执行顺序:
如果脚本的.bat和.cmd版本(test.bat,test.cmd)都在同一个文件夹中并且您运行没有扩展名(test)的脚本,则默认情况下脚本的.bat版本将运行,甚至在64位Windows 7上 . 执行顺序由PATHEXT环境变量控制 . 有关详细信息,请参阅Order in which Command Prompt executes files .
参考文献:
维基百科:Comparison of command shells
尽管如此,在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>
扩展名没有区别 . 处理文件的COMMAND.COM与CMD.EXE之间存在细微差别
差异:
.cmd文件在执行之前被加载到内存中 . .bat文件执行一行,读取下一行,执行该行...
当你执行一个脚本文件然后在它完成执行之前编辑它时,你可以遇到这个问题 . bat文件将被搞乱,但cmd文件不会 .
我相信如果您将ComSpec环境变量的值更改为%SystemRoot%system32 \ cmd.exe,那么文件扩展名是.BAT还是.CMD并不重要 . 我不确定,但这甚至可能是WinXP及以上的默认值 .
这些答案有点太长,专注于交互式使用 . 重要的区别是:
.cmd 防止在非NT系统上意外执行 .
.cmd 启用内置命令,在成功时将Errorlevel更改为0 .
编辑:默认情况下,命令扩展在Windows 2000或更高版本下的.bat和.cmd文件中都处于启用状态 .
在2012年及以后,我建议专门使用 .cmd .
.cmd和.bat文件执行不同,因为在.cmd errorlevel变量中,它可以在受命令扩展影响的命令上更改 . 这是真的 .
RE: 显然,调用command.com时有点复杂;
几个月前,在项目过程中,我们必须弄清楚为什么我们想要在CMD.EXE下运行的某些程序实际上是在COMMAND.COM下运行的 . 有问题的“程序”是一个非常古老的.BAT文件,它仍然每天运行 .
我们发现批处理文件在COMMAND.COM下运行的原因是它是从.PIF文件(也很古老)启动的 . 由于仅通过PIF可用的特殊内存配置设置变得无关紧要,我们将其替换为传统的桌面快捷方式 .
从快捷方式启动的同一批处理文件在CMD.EXE中运行 . 当你考虑它时,这是有道理的 . 我们花了这么长时间才弄明白的部分原因是因为我们忘记了它在启动组中的项目是PIF,因为它自1998年以来一直在 生产环境 .
不 - 丝毫没关系 . 在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 shell(COMMAND.COM)是专门为Windows NT设计的 . 当输入命令以供此shell执行时,它实际上不会执行它 . 相反,它打包命令文本并将其发送到32位CMD.EXE命令shell以供执行 . 因为所有命令实际上都是由CMD.EXE(Windows NT命令shell)执行的,所以16位shell继承了完整Windows NT shell的所有功能和设施 .
15 回答
来自this news group posting自Mark Zbikowski:
换句话说,如果将ERRORLEVEL设置为非0然后运行其中一个命令,则生成的ERRORLEVEL将为:
单独留在.bat文件中的非0值
在.cmd文件中重置为0 .
由于原帖是关于使用.bat或.cmd后缀的后果,不一定是文件中的命令...
.bat和.cmd之间的另一个区别是,如果两个文件存在相同的文件名和两个扩展名,那么:
在命令行输入filename或filename.bat将运行.bat文件
要运行.cmd文件,您必须输入filename.cmd
批处理中的所有工作都应该在cmd中工作; cmd提供了一些控制环境的扩展 . 此外,cmd由新的cmd解释器执行,因此应该更快(在短文件上不明显)并且在NTVDM仿真16位环境下运行时更稳定
稍微偏离主题,但你考虑过Windows Scripting Host?你可能会发现它更好 .
作为一名Cmd程序员,并且在整个网络上看,你使用哪一个并不重要,你可以在Windows 7上运行
.bat
程序,并在Windows 10上运行它 . 但是如果你想要它在Windows 10上,您可能无法在Windows 7上运行所有命令 ..cmd
的方式完全相同,并运行完全相同的程序和代码 .所有不同之处在于,它是同一程序的不同名称,只要它连接到
CMD.EXE
,它就会运行相同的命令 .这是我发现的一个区别:
EnableDelayedExpansion
在.cmd
文件中是 required .在
.bat
文件的情况下,默认情况下它是隐式的 . (Windows 10)这适用于
.bat
但在.cmd
文件的情况下始终为found
.将
line 2
更改为以下内容使其按预期工作:最后,对于
.cmd
文件,这可以正常工作:以下是本主题中各种答案和引用参考文献的经过验证的信息汇编:
command.com
是MS-DOS中引入的16位命令处理器,也用于Win9x系列操作系统 .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程序 .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
(之前存在,已被增强)功能:
CALL :label
执行顺序:
如果脚本的.bat和.cmd版本(test.bat,test.cmd)都在同一个文件夹中并且您运行没有扩展名(test)的脚本,则默认情况下脚本的.bat版本将运行,甚至在64位Windows 7上 . 执行顺序由PATHEXT环境变量控制 . 有关详细信息,请参阅Order in which Command Prompt executes files .
参考文献:
cmd.exe
command.com
维基百科:Comparison of command shells
尽管如此,在Windows 7上,BAT文件也存在这种差异:如果您在同一目录中创建文件TEST.BAT和TEST.CMD,并且在该目录中运行TEST,它将运行BAT文件 .
扩展名没有区别 . 处理文件的COMMAND.COM与CMD.EXE之间存在细微差别
差异:
.cmd文件在执行之前被加载到内存中 . .bat文件执行一行,读取下一行,执行该行...
当你执行一个脚本文件然后在它完成执行之前编辑它时,你可以遇到这个问题 . bat文件将被搞乱,但cmd文件不会 .
我相信如果您将ComSpec环境变量的值更改为%SystemRoot%system32 \ cmd.exe,那么文件扩展名是.BAT还是.CMD并不重要 . 我不确定,但这甚至可能是WinXP及以上的默认值 .
这些答案有点太长,专注于交互式使用 . 重要的区别是:
.cmd
防止在非NT系统上意外执行 ..cmd
启用内置命令,在成功时将Errorlevel更改为0 .编辑:默认情况下,命令扩展在Windows 2000或更高版本下的.bat和.cmd文件中都处于启用状态 .
在2012年及以后,我建议专门使用
.cmd
..cmd和.bat文件执行不同,因为在.cmd errorlevel变量中,它可以在受命令扩展影响的命令上更改 . 这是真的 .
RE: 显然,调用command.com时有点复杂;
几个月前,在项目过程中,我们必须弄清楚为什么我们想要在CMD.EXE下运行的某些程序实际上是在COMMAND.COM下运行的 . 有问题的“程序”是一个非常古老的.BAT文件,它仍然每天运行 .
我们发现批处理文件在COMMAND.COM下运行的原因是它是从.PIF文件(也很古老)启动的 . 由于仅通过PIF可用的特殊内存配置设置变得无关紧要,我们将其替换为传统的桌面快捷方式 .
从快捷方式启动的同一批处理文件在CMD.EXE中运行 . 当你考虑它时,这是有道理的 . 我们花了这么长时间才弄明白的部分原因是因为我们忘记了它在启动组中的项目是PIF,因为它自1998年以来一直在 生产环境 .
不 - 丝毫没关系 . 在NT上,.bat和.cmd扩展名都会导致cmd.exe处理器以完全相同的方式处理文件 .
有关MS TechNet(http://technet.microsoft.com/en-us/library/cc723564.aspx)的WinNT级系统上的command.com与cmd.exe的其他有趣信息: