setlocal 与 变量延迟

本条内容引用[英雄出品]的批处理教程:

要想进阶,变量延迟是必过的一关!所以这一部分希望你能认真看。

为了更好的说明问题,我们先引入一个例子。
例1:
 @echo off
 set
a=4
 set a=5 & echo
%a%
 pause
结果:4
解说:为什么是4而不是5呢?在echo之前明明已经把变量a的值改成5了?

让我们先了解一下批处理运行命令的机制:

批处理读取命令时是按行读取的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行),在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。我们现在分析一下例1,批处理在运行到这句“set
a=5 & echo
%a%”之前,先把这一句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!(没有为什么,批处理就是这样做的。)

而为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值。

那么如何开启变量延迟呢?变量延迟又需要注意什么呢?举个例子说明一下:

例2:
 @echo off
 setlocal
enabledelayedexpansion
 set a=4
 set a=5 & echo !a!
 pause

结果:5
解说:启动了变量延迟,得到了正确答案。变量延迟的启动语句是“setlocal
enabledelayedexpansion”,并且变量要用一对叹号“!!”括起来(注意要用英文的叹号),否则就没有变量延迟的效果。

分析一下例2,首先“setlocal enabledelayedexpansion”开启变量延迟,然后“set
a=4”先给变量a赋值为
4,“set a=5 & echo
!a!”这句是给变量a赋值为5并输出(由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此此时a的值就是5了)。

再举一个例子巩固一下。
例3:
 @echo off
 setlocal
enabledelayedexpansion
 for /l %%i in (1,1,5) do (
 set a=%%i
 echo
!a!
 )
 pause

结果:
1
2
3
4
5
解说:本例开启了变量延迟并用“!!”将变量扩起来,因此得到我们预期的结果。如果不用变量延迟会出现什
么结果呢?结果是这样的:
ECHO
处于关闭状态。
ECHO 处于关闭状态。
ECHO 处于关闭状态。
ECHO 处于关闭状态。
ECHO
处于关闭状态。
即没有感知到for语句中的动态变化。

提示:在没有开启变量延迟的情况下,某条命令行中的变量改变,必须到下一条命令才能体现。这一点也可以加以利用,看例子。

例:交换两个变量的值,且不用中间变量

@echo off
::目的:交换两个变量的值,但是不使用临时变量
::Code by JM
2007-1-24
CMD@XP
::出处:http://www.cn-dos.net/forum/viewthread.php?tid=27078
set
var1=abc
set var2=123
echo 交换前: var1=%var1% var2=%var2%
set
var1=%var2%& set var2=%var1%
echo 交换后: var1=%var1%
var2=%var2%
pause

setlocal 与 变量延迟的更多相关文章

  1. 变量延迟(setlocal)之浅见

    变量延迟,浅见认为就是变量预处理,在事先声明变量,告诉cmd环境哪个先哪个后.默认情况下是停用,可以用两种方法启用/停用: 一.cmd /v:on 和cmd /v:off ,范围在cmd这个环境直至e ...

  2. setlocal 本地变量详解

    命令 setlocal (开启本地变量)  endlocal (结束本地变量) 很多新手不理解这句话是什么意思,在批处理中有什么作用. 其实在批处理中 setlocal 作用很大,配合 endloca ...

  3. for批处理skip参数不支持变量延迟!n!的解决办法

    a.txt 文件a第1行 文件a第2行 文件a第3行 b.txt 文件b第1行 文件b第2行 文件b第3行 合并ab .bat @echo off REM 把两个文件逐行合并成一列 set n=0 f ...

  4. PHP eval变量延迟赋值

    $str = 'and {$prev}name like \'%五子棋%\'';$prev = "table.";eval("\$str = \"$str\&q ...

  5. 【转】BAT 批处理脚本 教程

    第一章 批处理基础第一节 常用批处理内部命令简介批处理定义:顾名思义,批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD.这些命令统称批处理命令.小知识:可以在 ...

  6. windows下Bat命令学习

    一.基础语法:1.批处理文件是一个“.bat”结尾的文本文件,这个文件的每一行都是一条DOS命令.可以使用任何文本文件编辑工具创建和修改.2.批处理是一种简单的程序,可以用 if 和 goto 来控制 ...

  7. Bat命令学习

    基础部分:====================================================================== 一.基础语法: 1.批处理文件是一个“.bat” ...

  8. 【工作笔记】BAT批处理学习笔记与示例

    BAT批处理学习笔记 一.批注里定义:批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD,这些命令统称批处理命令. 二.常见的批处理指令: 命令清单: 1.RE ...

  9. Windows 批处理(bat)语法大全

    本文是学习bat整理的笔记,由于内容较多,建议结合右侧文章大纲查看. %~dp0[获取当前路径] %~dp0 “d”为Drive的缩写,即为驱动器,磁盘.“p”为Path缩写,即为路径,目录 cd % ...

随机推荐

  1. 通过torodb && hasura graphql 让mongodb 快速支持graphql api

    torodb 可以方便的将mongo 数据实时同步到pg,hasura graphql 可以方便的将pg 数据暴露为graphql api,集成在一起真的很方便 环境准备 docker-compose ...

  2. android 图片解码显示流程

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...

  3. log4net保存到数据库系列一:WebConfig中配置log4net

    园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志 一.WebConfig中配置log4net 二.独立配置文件中配置log4net ...

  4. 消息队列在VB.NET数据库开发中的应用

    我们先简单的了解一下什么是消息队列(MSMQ)?消息队列是 Windows 2000(NT也有MSMQ,WIN95/98/me/xp不含消息队列服务但是支持客户端的运行)操作系统中通讯的基础,也是用于 ...

  5. c++中的流

    streambuf类为缓冲区提供内存,并提供了用于填充缓冲区,访问缓冲区,刷新新缓冲区和管理缓冲区内存的类方法. ios_base类表示流的一般特征,如是否可读,是二进制还是文本流等. ios类基于i ...

  6. kibana 与 grafana

    Kibana 和 Grafana 是两个开源工具,能可视化和推断大量日志数据内的趋势.Kibana 是一个分析和可视化平台,它可以让你浏览.可视化存储在Elasticsearch集群上排名靠前的日志数 ...

  7. 【python】实例-python实现两个字符串中最大的公共子串

    由于python中的for循环不像C++这么灵活,因此该用枚举法实现该算法: C="abcdefhe" D="cdefghe" m=0 n=len(C) E=[ ...

  8. 用exec调用带有output输出参数的存储过程

    用exec调用带有output输出参数的存储过程,想要得到输出参数的值,必须在调用参数后面加output关键字,如: declare @value int exec up_test    2,3,@v ...

  9. Xshell连接不上Ubuntu的解决方法

    xshell连接linux主机时,会出现错误:Could not connect to '127.0.0.1' (port 22): Connection failed.  但是这时能ping通. 通 ...

  10. Android自动化框架 模拟操作 模拟测试

    转自:http://bbs2.c114.net/home.php?mod=space&uid=1025779&do=blog&id=5322 几种常见的Android自动化测试 ...