你不是第一个陷入著名的“延迟扩展陷阱”的人(你也不会是最后一个)。
如果您想要使用在同一代码块中更改的变量,则需要延迟扩展(代码块是括号(
和)
中的一系列命令)。
延迟变量使用!var!
而不是%var%
进行引用。
原因是cmd
解析代码的方式。一整行或代码块一次性解析,将普通变量替换为它们在解析时的值。延迟变量在运行时评估。
以下是两个简单的批处理文件以演示:
setlocal EnableDelayedExpansion
set "var=hello"
if 1==1 (
set "var=world"
echo %var% !var!
)
setlocal EnableDelayedExpansion
for /L %%i in (1,1,5) do (
echo %random% !random!
)
注意: 一行也被视为一个块:
set "var=old"
set "var=new" & echo %var%
使用延迟扩展:
setlocal EnableDelayedExpansion
set "var=old"
set "var=new" & echo !var!
在命令提示符下,默认情况下未开启延迟扩展。如果您确实需要它,可以执行以下操作:
cmd /V:ON /C "set "var=hello" & echo !var!"
还有一种方法可以不使用延迟扩展来实现相同的效果(但是call
会花费一些时间,所以它更慢,但如果由于某些原因您不能/不想使用延迟扩展,则可以使用此方法):
setlocal DISabledelayedexpansion
for /L %%i in (1 1 5) do (
call echo %random% %%random%%
)
两种方法也可以用来显示类似数组的变量:
(这经常被问到,比如"包含另一个变量的变量"或"嵌套变量")
下面是在不同情况下使用这种类似数组的变量的集合:
使用延迟扩展:
setlocal ENableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
echo plain delayed: !var[%num%]!
for /L %%i in (4 1 4) do (
echo for delayed: !var[%%i]!
set a=%%i
call echo for delayed with variable: %%var[!a!]%%
)
不使用延迟扩展:
setlocal DISableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
call echo plain called: %%var[%num%]%%
for /L %%i in (4 1 4) do (
call echo FOR called: %%var[%%i]%%
set a=%%i
call echo FOR called with variable: %%var[%a%]%%
)
注意:在批处理文件之外,
setlocal
没有任何效果,因此
delayedexpansion
只在以下情况下有效:
- 在批处理文件中
- 当使用启用了延迟扩展的 cmd 启动时(默认情况下,cmd 运行时延迟扩展被禁用)
(如果您对
技术背景 或甚至
高级技术内容 感兴趣,请点击链接)