Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1491973
  • 博文数量: 226
  • 博客积分: 3997
  • 博客等级: 少校
  • 技术积分: 2369
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-19 17:26
个人简介

Never save something for a special occasion. Every day in your life is a special occasion.

文章分类

全部博文(226)

文章存档

2018年(5)

2017年(11)

2016年(1)

2015年(17)

2014年(14)

2013年(30)

2012年(5)

2011年(52)

2010年(107)

分类:

2010-11-17 22:19:16

什么是延迟变量扩展?

变量是程序中基本元素,所谓变量...不用解释吧!但在bat中你可能发现“变量”并不总是如期工作,如下代码,你觉得它会输出什么呢?

@echo off
set v=value
l&echo %v%
pause

执行后显示“ECHO 处于关闭状态”——不是应该显示value吗?要解释这个问题,你得明白cmd.exe解释器的“变量扩展”过程。

下面是高手的帖子,已经解释得很清楚了。

willsort

关于环境变量延迟扩展,使用set /?可以查看到部分说明,如果你觉得翻译水平精力,可以先chcp 437切换为英文再查看英文说明。

你常常会看到一对百分号包围起来的环境变量这称为“扩展(expansion)”,这个概念是从命令解释器的角度进行称谓的,从我们使用者的角度来看叫引用(Reference)。

命令解释器扩展环境变量的行为大致如下:
首先读取命令行的一条完整语句,在进行一些先期的预处理之后,命令被解释执行之前,会对其中用百分号闭合的字符串进行匹配。如果在环境空间中找到了与字符串相匹配的环境变量,则用其值替换掉原字符串及百分号本身;如果未得到匹配,则用一个空串替换。这个过程就是环境变量的“扩展”,它仍然属于命令行的预处理范畴

所谓一条“完整的语句”,在NT的命令解释器CMD中被解释为“for if else”等含有语句块的语句和用“& | && ||”等连接起来的复合语句。

因此,当CMD读取for语句时,其后用一对圆扩号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展。所以在for中的所有语句执行之前,所有的环境变量都已经被替换为for之前所设定的值,从而成为一个字符串常量——不再是变量!无论在for中将那些环境变量如何修改,真正受到影响的只是环境变量空间,而非for语句内部。

为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性——也就是说,当CMD读取了一条完整的语句之后,它不会立即执行变量的扩展行为——而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被“延迟”了。

延迟环境变量扩展特性在CMD中缺省是关闭的,开启它的方法目前有两个:一是CMD /v:on,它会打开一个新的命令行外壳,在使用exit退出这个外壳之前,扩展特性始终有效,常用于命令行环境中;二是setlocal EnableDelayedExpansion,它会使环境变量的修改限制到局部空间中,在endlocal之后,扩展特性和之前对环境变量的修改将一同消失,常用于批处理语句中。

 

阅读(1241) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~