[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

批处理setlocal本地变量详解(2008-10-07更新)

setlocal 本地变量详解
:: code 随风 @bbs.bathome.net 2008-10-01
setlocal 本地变量详解
命令 setlocal (开启本地变量)  endlocal (结束本地变量)
很多新手不理解这句话是什么意思,在批处理中有什么作用。
其实在批处理中 setlocal 作用很大,配合 endlocal (结束本地变量)
它可以使你的代码更简洁,易读,且不容易出错。
举例:
假设你在批处理的开头部分有这么一句  set var=123
那么在批处理结束以前,变量 var 的值就永远是 123
除非你 运行了  set "var=" 来把它的值清空。或 set var=别的什么 把它的值改变
否则它的值永远是 123
当写某些代码时,需要把变量的值累加,如: set var=%var%567 此时var的值就是 123567
或是 set /a var+=1 (这是当var的值是有效数字时)每运行一次,var的值就会加1
但当某段代码需要重复运行时,我们有时、甚至是经常需要var的值回到原始的值,即:123
你可能会说这还不好办,一句就ok 了 set var=123或set var=
不错,确实是这样,但如果我们需要将一大堆的变量都会回到原始值呢?
比如: var num a b c d e f .........
你难道要
set var=
set num=
set a=
set b=
........
........
这样吗?
有了setlocal 和 endlocal 就不用这么麻烦了。
看代码
  1. @echo off
  2. set var=123
  3. set num=4456
  4. set a=ham
  5. setlocal
  6. set var=abcd
  7. set num=jkl
  8. set a=efg
  9. set max=1234567
  10. ::到了这一步,我想不用echo你应该也都知道,这三个变量的值改变了,
  11. ::并且还给一个新的变量赋了值 max
  12. ::对于不熟悉setlocal 和 endlocal 命令的朋友来说,要想让这
  13. ::三个变量回到开始的值,可能就只有回到开头那三句去了,其实不用。
  14. ::一句就可以了,看下面的
  15. endlocal
  16. echo %var% %num% %a%
  17. echo %max%
  18. pause
复制代码
看到区别了吗?
不错,setlocal 和 endlocal 这两句中间的命令给所有的变量赋的值都消失了,
就好像从没有运行过它们一样。
运行 setlocal 以前变量的值是什么 在运行 endlocal 以后,
又回到了什么。如果之前是空值,即:没有赋值
如:例子中的 max 那么 echo %max% 就会显示 ECHO 处于关闭状态
以前 cn-dos 里有位版主(好像就是我们论坛的第三方软件版块的现任版主)曾经很形象的解释过这个问题,
这里借用一下 ,记得不是很清楚了,加一点我自己的描述。
他说:
  批处理运行时会开辟一块地方给变量,我们可以把它想像为一块黑板,
你可以在黑板上任意写字,在批处理中这种写字,就是给变量赋值或清空或改变变量的值
如:set var=123  set num=   set /a str+=1 set var=%var% %num% 等等之类的。
而 setlocal 命令就是在黑板中又划出一块方块来,你在这之后所写的字就全在这个方块中,
(当然这个方块的容量、大小不会有什么限制,你或者把他理解为在这个黑板上又覆盖了一块同样大小的新的黑板,更为恰当。当然这个黑板的容量大小应该要减去你在原来那块黑板上所写的内容,这个就不在这里讨论了,知道个大概就行。)
当运行 endlocal (结束变量)后,相当于把你在原来那块黑板上划的方块擦掉了,连内容一起擦掉了。
又或者说,把这个新的黑板拿走了,你在这个新黑板上写的字也都没有了,回到你面前的又是原来的那块黑板,当然你以前写在上面的字仍然还在。它不会擦掉你的,也不会自动给你写些新东西上去。
也就是 原来的变量还是原来的值,原来没有赋值的,仍然是空值。不管你在那块新黑板上写过什么,都过去了,就象什么也没发生过一样。
唉!
打字本来就慢,说了一大窜,我自己都不知道在说什么了,感觉跑了题似的。。。
写教程还真是难。。。很简单的事,要写出来还真是不容易,要让没接触过的人懂就更不容易了,
没办法,就这表达能力了,各位新人将就着看吧,不懂就发帖提问。。
关键还是自己多实践、琢磨。

补充:
  当新黑板上的内容与老黑板上的内容发生冲突时,则以新黑板上的内容为准,
  若老黑板上的内容没与新黑板的内容冲突时,老黑板上的内容在新黑板中仍然有效。
在提一句,新黑板最多只能连续覆盖32块,否则就会提示 “以达到最大递归层”的错误信息。
所谓 “连续覆盖”就是运行了 setlocal 而没有运行 endlocal 的情况。


[ 本帖最后由 随风 于 2010-9-2 10:58 编辑 ]
2

评分人数

技术问题请到论坛发帖求助!

虽然会用,但要我写出来,真是不知从哪入手。
原来只知其然,不知其所以然。

听了黑板的比喻,明白多了。

TOP

学习中.........

TOP

我认为不应该用黑板等来举例,说严重点呢只会误导别人,setlocal就是setlocal,不需要理由,不明白可以多练习,学批处理、脚本或计算机语言,不需要这样的比喻,如果一个人靠这样的比喻来学习,那他不可能精通。

TOP

回复 4楼 的帖子

虽说学习任何一种知识都需要自己去理解才能内化,才能步入更高的境界,但要过入门的槛,依然需要贴切的比喻和生动的教学。幼儿园的老师教数字时,会说“1”像竖起的棍子,“2”像一只天鹅。只要写“1”时像竖直的棍,那“1”字是标准而美观的,“2”亦如此。若没有这样的比喻,小孩子会把“1”画的歪歪扭扭,不像天鹅的“2”也就没有美感了。综上,比喻式的教程是可取的,甚至可以说对于入门的同学是有帮助有必要的。
静水流深...

TOP

随风大哥

很早注册的时候经常见随风大哥,
呵呵。,前段时间一直没有见随风,
又见你发表文章了,辛苦了。。。。
一后多回来指导大家啊。。我都学批处理一年了,
还是有很多不懂。呵呵。。。。。。。。。。。。。。。。。。。。。。

TOP

好帖!很形象的比喻,理解了!

TOP

一直想如果批处理有个可以清除已定义变量的命令就好,没想到还真的有。学习了,谢谢你!

TOP

随风出品,必属精品。呵呵。。。
虚心使人进步 细节成就完美

TOP

也就是说可以这样了
  1. @echo off
  2. set abc=楼主万岁
  3. setlocal
  4. set abc=才怪
  5. endlocal
  6. echo abc
  7. pause>nul
复制代码
开玩笑,别见怪^_^

TOP

  1. @echo off
  2. set abc=楼主万岁
  3. setlocal
  4. set abc=才怪
  5. endlocal
  6. echo %abc%
  7. pause>nul
复制代码
楼上的忘记加百分号了!
后面的“才怪”两字 作用域 只是在 setlocal 至 endlocal之间!
所以就后打印出来的是 “楼主万岁”。。

如果改成下面这样那就不一样了!

  1. @echo off
  2. setlocal
  3. set abc=楼主万岁
  4. set abc=才怪
  5. echo %abc%
  6. endlocal
  7. pause>nul
复制代码


打印出来的是“才怪”。

[ 本帖最后由 specter 于 2008-12-9 14:14 编辑 ]

TOP

总结一下

写了这么多,其实就一句话:“endlocal后, 原来的变量还是原来的值,原来没有赋值的,仍然是空值。”

TOP

十分同意11楼 作用域 的说法。

TOP

哦!还有这个东东!笑纳了!

TOP

原来是这么个情况!

看了此贴才真正明白setlocal 和endlocal。顺便问一下,setlocal EnableDelayedExpansion    这个多加了一个DelayedExpansion   这是什么情况?

TOP

返回列表