成功后哪个cmd.exe内部命令将ERRORLEVEL清除为0?

dbe*_*ham 21 cmd batch-file errorlevel

在Windows批处理脚本中处理错误的常用方法是使用
if errorlevel 1 ...或等if %errorlevel% neq 0 ....通常,人们希望错误处理代码保留ERRORLEVEL.

我相信所有外部命令总是会导致ERRORLEVEL被设置为某个值,因此错误处理代码必须在执行外部命令之前在环境变量中保留ERRORLEVEL.

但内部命令怎么样?问题是,一些内部命令在成功时将ERRORLEVEL清除为0,而有些则没有.而且我找不到任何指定哪些命令做什么的文档.

所以问题是,哪些内部命令成功后将ERRORLEVEL清除为0?不是关于返回的ERRORLEVEL代码的一般问题,而是严格关于成功结果的问题.

有些帖子如何将ERRORLEVEL重置为零的最简单方法是什么?Windows批处理文件:.bat vs .cmd?给出部分答案.但我从未见过全面的清单.

注意: 多年来我一直很好奇.所以我最终决定进行一系列实验并得出一个明确的答案.我发布此问答来分享我发现的内容.

dbe*_*ham 24

这个答案基于我在Windows 10下运行的实验.我怀疑使用cmd.exe的早期Windows版本存在差异,但这是可能的.

另请注意 - 当内部命令遇到错误时,此答案不会尝试记录ERRORLEVEL结果(除了关于DEL和ERASE的小位)

命令之间不仅存在差异,而且单个命令的行为可能会有所不同,具体取决于它是从命令行运行,还是在带有.bat扩展名的批处理脚本中运行,还是来自具有扩展名的批处理脚本.cmd.

无论上下文如何,以下命令集都不会在成功时将ERRORLEVEL清除为0,而是保留先前的ERRORLEVEL:

  • 打破
  • CLS
  • 回声
  • ENDLOCAL
  • FOR:显然,DO子句中的命令可以设置ERRORLEVEL,但是至少有一次迭代的成功FOR不会自己将ERRORLEVEL设置为0.
  • IF:显然,IF执行的命令可能设置ERRORLEVEL,但成功的IF不会自己将ERRORLEVEL设置为0.
  • KEYS
  • 暂停
  • POPD
  • RD
  • REM
  • RMDIR
  • 转移
  • 开始
  • 标题

无论上下文如何,下一组命令总是在成功时将ERRORLEVEL清除为0:

  • 光盘
  • CHDIR
  • 颜色
  • 复制
  • 日期
  • DEL:始终清除ERRORLEVEL,即使DEL失败(除非在没有任何文件参数的情况下运行).
  • DIR
  • 删除:即使ERASE失败,也始终清除ERRORLEVEL.(运行时没有任何文件参数).
  • MD
  • MKDIR
  • MKLINK
  • 移动
  • PUSHD
  • REN
  • 改名
  • SETLOCAL
  • 时间
  • 类型
  • VER
  • 校验
  • VOL

然后,如果从命令行或带有.bat扩展名的脚本发出,则这些命令在成功时不会清除ERRORLEVEL ,但如果从具有.cmd扩展名的脚本发出,则将ERRORLEVEL清除为0 .有关详细信息,请参阅/sf/answers/10429401/https://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.admin/XHeUq8oe2wk/LIEViGNmkK0J.

  • ASSOC
  • DPATH
  • FTYPE
  • 路径
  • 提示

最后,有些命令不能完全适合任何先前的类别:

  • CALL:如果:例程或批处理脚本被调用,则ERRORLEVEL由CALLed脚本或:例程专门控制.但是,如果CALLed命令没有以其他方式设置它,则对命令的任何其他类型的成功CALL将始终将ERRORLEVEL清除为0.
    示例:call echo OK.

  • 退出:如果没有使用/B,则cmd.exe会话终止,并且不再有ERRORLEVEL,只有cmd.exe返回代码.显然EXIT /B 0将ERRORLEVEL清除为0,但EXIT /B没有值保留先前的ERRORLEVEL.

我相信这会占所有内部命令,除非我错过了一个没有记录的命令.