Board logo

标题: [转贴] 批处理延迟环境变量扩展 [打印本页]

作者: vyuwwen1985    时间: 2009-1-15 10:58     标题: 批处理延迟环境变量扩展

延迟环境变量扩展


       延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫扩展!

CMD在解释我们的命令的时候,首先会读取命令行一条完整的命令,然后对其进行一些命令格式的匹配操作,看你所输入的命令格式是不是符合他的要求.

       如果我们要在我们的命令中引用一些变量,那么我们如何让CMD在解释我们的命令时,能识别出这个变量呢?这时我们就可以在变量名字两边加一个%号,如%name%.当CMD在对读取我们的整行命令进行格式匹配的时候,就会发现name这个字符两边加了%号,就不会把他当作普通字符处理,而是会把他当作一个变量处理,变量名叫name!然后CMD就会找到变量名对应的值,用变量名的值替换掉这个变量名字(name),(如果变量名不存在值,就返回空值).再将这个替换好并且匹配的命令执行!这个替换值的过程,就叫做变量扩展,说白了就是把变量的名字,用他的值给替换掉后执行!也就是批处理如何识别一个变量的过程.

(注意:这里只是变量的扩展的意思,不是延迟环境变量扩展,要理解延迟环境变量扩展,必须先理解什么是变量的扩展) 也就是批处理如何识别一个变量的过程.

例如这个BAT

set var=test

echo %var%

CMD在读取到echo %var%这句命令后,就会进行匹配操作,它马上就发现var字符两边有%号,这时他就会把他当作一个变量处理,查看这个var变量名是不是有值,如果有就用他的值把变量名var给替换掉,这里我们的VAR在上一条命令set var=test中,给var赋值为test,所以他会用test把%var%这个变量名替换掉,替换后的结果就为echo test了.这些步骤都是CMD进行匹配操作的步骤,匹配完后,他再执行echo test这条语句,这时我们的CMD中就会echo出一个test了.

什么是环境变量扩展知道了,那什么是延迟环境变量扩展呢?

       在理解环境变量扩展时,我们知道CMD在解释命令时,首先会把一条完整的命令进行读取,然后进行匹配操作,匹配时他会把命令里的变量用变量的值个替换掉,然后执行这个替换好的命令.

问题就出在"一条完整的命令",在BAT中,IF FOR这样的命令都可以加括号,将一些命令嵌套在里面执行.这样的话对于一条可以加扩号嵌其他命令的命令,他的完整格式就是

for %%i in (....)这样一个整体.此时,如果我们如果在括号里面嵌入一些设置变量值的命令,就会出现问题了!

看例子

@echo off

for /l %%i in (1,1,5) do (

    set var=%%i

    echo %var%

)

执行后会显示5个空行的错误提示!为什么?根据我们上面说的知识来理解


通过这两个例子,大家因该已经理解,如果只有环境变量扩展这个过程的话,如果我们在可以嵌套命令的命令中执行赋值操作时,会让我们的BAT出现给变量赋值的问题.

那么这个时候"延迟环境变量扩展",这个概念就被提出来了

在批处理中,我们可以用setloacl ENABLEDELAYEDEXPANSION这个命令来启用"延迟环境变量扩展"

在我们启用了"延迟环境变量扩展"后,当CMD在解释涵有嵌套格式的命令时,他会把嵌套的命令一条一条的先执行一次,然后再进行匹配操作,这样我们的赋值操作就会完成.并且再"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量,如没启用来变量用%name%这样的格式判断,启用后就用!name!这样的格式判断了,这个符号我们需要注意!

例子:

@echo off

setlocal ENABLEDELAYEDEXPANSION

set var=1

for /l %%i in (1,1,5) do (

    set /a var+=%%i

    echo !var!

)
pause


这样大家因该明白什么是延迟环境变量扩展了吧.

再来一个例子

@echo off

set var=test & echo %test%

pause

这条命令放在一行,表示他是一条完整的命令,不启用"延迟环境变量扩展",就会出现上面的赋值错误!

改成这样

@echo off

setlocal ENABLEDELAYEDEXPANSION

set var=test & echo !var!

pause.


作者: Batcher    时间: 2009-1-15 13:02

所发代码若不止一行,请务必用code标记把代码部分首尾括起来,以便他人复制。

Q: 如何用code把代码扩起来?
A: http://bbs.bathome.net/thread-404-1-1.html
作者: januapr    时间: 2009-8-8 05:02

讲得够明白!新手有福了!
谢谢LZ!
作者: fuwei880306    时间: 2009-12-16 20:38

批处理总是断断续续地学着,今天学到了原来还在环境变量这回事,奇怪以前咋就没碰到过
作者: zqz0012005    时间: 2009-12-16 21:04

http://www.bathome.net/forum-25-1.html
本版规则
  1、本版以转载非本论坛的优秀批处理代码为主,其他话题一律不得在此发布;
  2、本版块所认定的优秀代码,是指具备一定的通用性,能显著减少用户重复操作的代码;
  3、所发代码务必在显著位置注明作者及详细出处(最好能带上链接地址),以示对原作者辛勤劳动的尊敬;若原始信息难以获取,必须标明大致来源;
  4、所发代码务必用[code] 和[/code]标记把代码部分首尾括起来,以便他人复制;

http://hi.baidu.com/377211550/blog/item/d00ab68d37c5b11bb31bbaa2.html

http://blog.csdn.net/xpwang168/archive/2009/01/12/3757974.aspx

http://hi.baidu.com/7764sky/blog/item/b47d6e10771a5d04203f2efa.html

[ 本帖最后由 zqz0012005 于 2009-12-16 21:05 编辑 ]
作者: mstsc    时间: 2011-5-5 20:48

学批处理 的知识,现在都是这里找点那里找点,自己慢慢在论坛里看帖子,才知道还有这些东西自己没学到。希望论坛那位大大能帮我们新人整理点系统的批处理知识,那我们就有福了。在这之前还是自己慢慢找慢慢看慢慢学
作者: Batcher    时间: 2011-5-5 21:46

7# mstsc


批处理新手入门导读
http://bbs.bathome.net/thread-75-1-1.html
作者: 习风口    时间: 2011-5-15 21:03

其实说白了就是替换变量的时候变量的时候变量还没赋值
作者: 594850072    时间: 2012-1-25 20:59

又学了我了点知识   谢谢
作者: 秋风·飞扬    时间: 2012-5-9 11:12

回复 9# 习风口


    恩,这样说直白,也容易理解,教程嘛,对于我这种新手上路,感觉就应该大众化,普通化,生动一点,直白一点,弄一些专业词汇绕来绕去的不太好
作者: gawk    时间: 2012-5-9 13:15

回复 11# 秋风·飞扬


    新手上路没关系,但是上路的时候不要自己随便发明词汇和语法就行。
作者: 秋风·飞扬    时间: 2012-5-9 13:43

回复 12# gawk


    嘎嘎,最近又发明了不少,后来自己又偷偷摸摸的改掉了,论坛上还有的就是修改XML文件的那篇,发明创造了.....总之就像赵本山说的,改了再犯,犯了再改....不过最有改进的就是发明创造的频率越来越小了,哈哈




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2