【批处理DOS-CMD-汇总】扩展变量-延迟变量cmd /v:on、cmd /v:off、setlocal enabledelayedexpansion、DisableDelayedExpansion

Reference

批处理命令——for - kaizen - 博客园

Bat脚本之延时变量cmd /v:on_komomon‘s blog的博客-CSDN博客_bat延迟变量

一、“延迟变量”的存在背景

批处理的执行过程是“自上而下,逐条执行”,而“逐条执行”不代表“逐行执行”。

因为一条指令可能占据多行。

在复合语句中,整个复合语句是一条完整的语句,而无论这个复合语句占用了多少行的位置。常见的复合语句有:for语句、if……else语句、用连接符&、||和&&连接的语句,用管道符号|连接的语句,以及用括号括起来的、由多条语句组合而成的语句块。

在非复合语句中,如果该语句占据了一行的位置,则该行代码为一条完整的语句。  

而批处理在执行一条语句前会进行“预处理”,预处理过程会把所有变量识别出来,直接给各处变量赋上现有值。

即使一条语句中,涉及同一变量的操作有前有后,在前面改变了变量的值,这个更新值无法传至后面的变量,因此后面的变量在执行命令时起作用的是旧值(但往往我们想要前面执行命令得到的更新值直接传给后面的变量)。

例如,你编写了一个脚本文件。

chcp 65001
@echo off 
set school=湘潭大学
echo "我现在就读于%school%"
echo "经过四年的时间,我收到重庆大学的录取通知书"
set school=重庆大学 & echo 我现在即将就读于%school% 
pause>nul

执行结果如下。是不是很怪?按道理应该怎么样,先把自己的school设定为重庆大学后,对外输出的应该是“我现在即将就读于重庆大学”吧。

原因就是因为命令【set school=重庆大学 & echo 我现在即将就读于%school% 】是一条复合语句,在预处理过程中后面的school变量已经被赋值“湘潭大学”了。

有没有一种选项或开关,我们开了它之后,就能在不改变原先语句结构的基础上,将复合语句后面的变量更替至前面执行的最新值。

有有有!当然有!欲知后事如何,请听后文分解!

二、在cmd窗口中打开延迟变量

在cmd窗口中,我们执行命令【cmd /?】可以得到相关帮助信息,下面重点引述(其他不相关的全删了,如果感兴趣其他参数可以自行打印)。

C:\Users\Administrator>cmd /?
启动 Windows 命令解释器的一个新实例

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
    [[/S] [/C | /K] string]

/V:ON   使用 ! 作为分隔符启用延迟的环境变量
        扩展。例如,/V:ON 会允许 !var! 在执行时
        扩展变量 var。var 语法会在输入时
        扩展变量,这与在一个 FOR
        循环内不同。
/V:OFF  禁用延迟的环境扩展。

延迟环境变量扩展不按默认值启用。你
可以用/V:ON 或 /V:OFF 开关,为 CMD.EXE 的某个调用而
启用或停用延迟环境变量扩展。你
可以在机器上和/或用户登录会话上启用或停用 CMD.EXE 所有
调用的延迟扩展,这要通过设置使用 REGEDIT.EXE 的注册表中的
一个或两个 REG_DWORD 值:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion

        和/或

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion

到 0x1 或 0x0。用户特定设置
比机器设置有优先权。命令行开关
比注册表设置有优先权。

在批处理文件中,SETLOCAL ENABLEDELAYEDEXPANSION 或 DISABLEDELAYEDEXPANSION
参数比 /V:ON 或 /V:OFF 开关有优先权。请参阅 SETLOCAL /?
获取详细信息。

如果延迟环境变量扩展被启用,
惊叹号字符可在执行时间被用来
代替一个环境变量的数值。

我们从帮助信息可以知道,大致分为两种打开延迟变量开关的方式,不管哪种都需要把变量两旁的百分号%改成感叹号!。

第一种,在cmd中打开延迟变量,其中又分为临时性地通过命令【cmd /v:on】或命令【cmd /v】打开和永久性地修改注册表变量打开。

第二种,在批处理脚本中打开延迟变量,其中又分为临时性地通过命令【SETLOCAL ENABLEDELAYEDEXPANSION】打开和永久性地修改注册表变量打开。

我们试试第一种的临时修改版本。

执行命令【cmd /v:on】后,便进入延迟变量扩展环境,cmd窗口标题后面也加了命令代码。

再执行命令。

set CQ=1
set /a CQ+=1 & echo !CQ!

结果如下所示,set /a CQ+=1的输出是2,并且后面的echo也输出了2,说明后面的echo使用的是前一个set执行后的最新值。 

我们可以通过命令【exit】或者命令【cmd /v:off】来退出延迟变量状态。

退出后,再执行上述命令,结果如下。

下面我们继续讲解如何在批处理脚本使用延迟变量机制。

三、在批处理脚本中打开延迟变量

新建一个bat文件,代码如下。

chcp 65001
@echo off 
set school=湘潭大学
echo "我现在就读于%school%"
echo "经过四年的时间,我收到重庆大学的录取通知书"
set school=重庆大学 & echo 我现在即将就读于%school%
echo 这次输出错了
echo "打开延迟变量试试"
setlocal EnableDelayedExpansion
set school=湘潭大学
set school=重庆大学 & echo 我现在即将就读于!school! 
echo "终于正确了"
echo "再关闭延迟变量试试"
setlocal DisableDelayedExpansion
set school=湘潭大学
set school=重庆大学 & echo 我现在即将就读于%school%
echo "果然又错了哈哈哈"
pause>nul

执行之后,输出结果如下。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值