batch-file - .bat 和 .cmd 在 ERRORLEVEL 上不同,谁决定 SET 的行为?

标签 batch-file

正如我刚刚发现的,SET 的行为对于 .bat.cmd 是不同的。我的实验表明,SET 的行为由启动批处理文件的扩展名(.bat 或 .cmd)决定,而不是由 SET 语句所在的文件扩展名决定。

这是 Windows NT CMD 批处理脚本引擎的一个模糊角落,Ben Hoffstein talks about it a bit .而我想知道,我的结论是否正确?或者,Microsoft 文档是否在某处正式讨论过这个问题?

我也想知道,有没有办法查看,甚至改变当前的模式?bat模式还是cmd模式?如果两者都不是,我必须接受这样一个事实,即我们批处理脚本作者(尤其是将批处理编写为函数时)不能做出任何假设。

下面是我的实验

从 Windows 7 SP1 运行。

淋浴器.bat

@echo off
setlocal EnableDelayedExpansion

call :SetErrorlevel 40
set var=1
echo Err=%ERRORLEVEL%

exit /b 0

REM ==== Functions below ====

:SetErrorlevel
exit /b %1

showerr.cmd

与 showerr.bat 相同。

启动子命令.bat

call showerr.cmd

开始subbat.cmd

call showerr.bat

结果如下:

enter image description here

enter image description here

最佳答案

这并不让我感到惊讶,尽管我之前从未测试过这个特定点......

以下信息来 self 的个人经历。据我所知,这在任何地方都没有记录

通过 call subFile.bat 调用的“子程序”就是我所说的内部子程序。它继承来自其父级的几种状态,如“回声开/关”等。现在,我知道它也继承了“BAT|CMD”模式。

当然,内部子程序与其父程序共享的最广为人知的值是环境变量。

通过 cmd/C subFile.bat 调用的子程序是一个外部子程序。当它启动时,它有一组新的几个状态的初始值,包括“BAT|CMD”模式。

查看此测试:

开始-SubBat.cmd

call ShowErr.bat
cmd /C ShowErr.bat

输出:

Err=0
Err=40

start-SubCmd.bat

call ShowErr.cmd
cmd /C ShowErr.cmd

输出:

Err=40
Err=0

知道什么是“当前模式”的方法非常简单:首先通过 verify other 2>NUL 将错误级别设置为 1(这是 MS 建议的方法),然后执行 set var=1。如果新的 %errorlevel% 为 1,则处于 BAT 模式;如果为 0,则表示您处于 CMD 模式。

只是为了完成这个主题,一个“子程序”通过它的名字执行,没有 call 也没有 cmd/C 命令(即只是 subFile.bat) 称为覆盖:它替换各个方面的调用程序。

this answer表 3 中简要描述了当它们被放置在 BAT 或 CMD 文件中时改变它们修改 %errorlevel% 方式的命令。 .

关于batch-file - .bat 和 .cmd 在 ERRORLEVEL 上不同,谁决定 SET 的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71477056/

相关文章:

batch-file - “NET USE”在 CMD 中有效,但在批处理中无效

windows - Windows中用FOR遍历路径变量

batch-file - 如何制作MD5批量病毒扫描程序?

arrays - 批处理 (CMD) 迭代两个数组(由 2 个 .txt 文件组成)

java - 调用批处理运行jar的方法

batch-file - 批处理数学命令不起作用

windows - 使用 Windows REN 命令从文件名中删除前缀

javascript - 从网站上给定 SKU 编号列表中提取产品名称的最佳方法是什么?

batch-file - cmd.exe %errorlevel% 9009 的官方 MS 引用

javascript - 我如何从批处理文件调用带有 2 个参数的 javascript 函数并将结果返回到环境变量