Windows 具有旧值的批量回显变量

Windows Batch echo variable with old value

这是一个示例:

D:\>set var=123

D:\>set var=456 & echo %var%
123

D:\>set var=789 & echo %var%
456

var 变量中设置了一个新值,但是 echo 仍然显示旧值。

有人知道发生了什么事吗?以及如何获得正确的价值?

当请求执行一个命令或命令块(命令连接或括在括号中)时,解析器会在 之前用变量中的内容替换对变量的所有读取操作开始执行 commands/block

在您的情况下,变量中的值在执行时更改,但 echo 到控制台的值是在更改之前确定的。这可以用

进行测试
set "var=abc"
set "var=123" & set var & echo %var%

set var 将显示变量中的正确值(在此命令中没有变量读取操作被解析器替换)但 echo 将显示旧值(替换为命令执行前的解析器)。

在批处理文件中,通常的处理方法是使用延迟扩展(setlocal enabledelayedexpansion 命令),这将允许您在需要时更改从 %var% 访问变量的语法into !var!,指示解析器必须延迟读取操作,直到执行命令。

但是您不能从命令行启用延迟扩展。也许它已启用(不是默认状态)并且您将能够使用它

set "var=abc"
set "var=123" & echo !var!

但如前所述,这不是通常的情况。您将需要转义百分号以对解析器隐藏变量并强制对该行进行第二次解析器评估。

set "var=abc"
set "var=123" & call echo ^%var^%

或者您可以生成一个单独的 cmd 启用延迟扩展的实例

set "var=abc"
set "var=123" & cmd /v /c"echo !var!"

这与delayedexpansion有关。

整个命令被解析,任何 %var% 被替换为当时的当前值。

然后执行命令。该值是变化的,但是 echo 命令已将变量替换为解析时的值。

您可以尝试 set var 显示当前值,或 for /f "tokens=1*delims==" %%a in ('set var 2^>nul') do echo %%b 或更稳健的 for /f "tokens=1*delims==" %%a in ('set var 2^>nul') do if /i "%%a"=="var" echo %%b

2^>nul 抑制错误消息的地方不应该 var 定义。插入符号 (^) 需要告诉 cmd 重定向程序是 for 应该执行的命令的一部分。

由于set var会列出所有以var开头的变量,所以最后一种方法比前一种更健壮。