Board logo

标题: [其他] 批处理中setlocal与endlocal怎么用? [打印本页]

作者: Clark2505    时间: 2008-8-7 22:25     标题: 批处理中setlocal与endlocal怎么用?

有没有人讲一下 setlocal与endlocal怎么用?
自带的说明让人越看越晕~~~
作者: tjtchly    时间: 2008-8-7 23:43

Setlocal启动批处理文件中环境变量的本地化。本地化将持续到出现匹配的 endlocal 命令或者到达批处理文件结尾为止。



语法setlocal {enableextension | disableextensions} {enabledelayedexpansion | disabledelayedexpansion}

参数enableextension
启用命令扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。

disableextensions
禁用命令扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。

enabledelayedexpansion
启用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。

disabledelayedexpansion
禁用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。

/?
在命令提示符下显示帮助。





注释
使用 setlocal
当您在脚本或批处理文件外使用 setlocal 时,将没有效果。
更改环境变量
运行批处理文件时使用 setlocal 更改环境变量。运行 setlocal 后所做的环境更改是批处理文件的本地更改。Cmd.exe 在遇到 endlocal 命令或者到达批处理文件的结尾时将恢复上一次的设置。
在批处理程序中可以包含多个 setlocal 或 endlocal 命令(即嵌套命令)。
测试批处理文件中的命令扩展
setlocal 命令设置 ERRORLEVEL 变量。如果遇到 {enableextension | disableextensions} 或 {enabledelayedexpansion | disabledelayedexpansion},ERRORLEVEL 变量将设置为零 (0)。否则,该变量将设置为 1。在批处理脚本中使用该命令可以确定扩展是否可用,例如:
    verify other 2>nul setlocal enableextensions if errorlevel 1 echo Unable to enable extensions因为当禁用命令扩展时,cmd 不会设置 ERRORLEVEL 变量,所以 verify 命令在与无效参数配合使用时,会将 ERRORLEVEL 变量初始化为非零值。而且,如果 setlocal 命令与参数 {enableextension | disableextensions} 或 {enabledelayedexpansion | disabledelayedexpansion} 配合使用,并且没有将 ERRORLEVEL 变量设置为 1 (1),则命令扩展将不可用。
有关启用和禁用命令扩展的详细信息,请参阅“相关主题”中的“cmd”。

示例可以将批处理文件中的环境变量本地化,如下所示:
  rem *******Begin Comment************** rem This program starts the superapp batch program on the network, rem directs the output to a file, and displays the file rem in Notepad. rem *******End Comment************** @echo off setlocal path=g:\programs\superapp;%path% call superapp>c:\superapp.out endlocal start notepad c:\superapp.out
格式图例格式意义斜体
用户必须提供的信息
粗体
用户必须严格按照其显示键入的元素
省略号 (...)
可在命令行中重复多次的参数
在括号 ([]) 之间
可选项目
在大括号 ({}) 之间;将选项用管线 (|) 隔开。例如:{even|odd}
用户必须从中只选择一个选项的选项组
Courier font
代码或程序输出

这是关于Setlocal微软官方的解释:http://technet2.microsoft.com/windowsserver/zh-chs/library/d226cd43-42c1-46ae-87f1-b3e78400b4372052.mspx?mfr=true
**************************************************************************************************************************************************
Endlocal结束批处理文件中环境更改的本地化,将环境变量还原为匹配 setlocal 命令前的值。



语法endlocal

参数/?
在命令提示符下显示帮助。



注释
必须在脚本或批处理文件中使用 endlocal。如果在脚本或批处理文件之外使用 endlocal,则该命令无效。
在批处理文件的结尾处有一个隐含的 endlocal 命令。
通过启用命令扩展名(即,默认值),endlocal 命令将命令扩展名的状态(即,已启用或已禁用)还原到执行匹配 setlocal 命令之前的状态。有关启用和禁用命令扩展的详细信息,请参阅“相关主题”中的“cmd”。

示例在批处理文件中可以本地化环境变量。例如:
@echo off
rem This program starts the superapp batch program on the network,
rem directs the output to a file, and displays the file
rem in Notepad.
Setlocal
path=g:\programs\superapp;%path%
call superapp>c:\superapp.out
endlocal
start notepad c:\superapp.out

格式图例格式意义斜体
用户必须提供的信息
粗体
用户必须像显示的一样准确键入的元素
省略号 (...)
可在命令行中重复多次的参数
在括号 ([]) 之间
可选项目
在大括号 ({}) 之间;将选项用管线 (|) 隔开。例如:{even|odd}
用户必须从中只选择一个选项的选项组
Courier font
代码或程序输出

这是关于Endlocal的解释出处:http://technet2.microsoft.com/windowsserver/zh-chs/library/5f5ac795-ae6b-43b3-ae29-1783e480f6e22052.mspx?mfr=true
作者: null    时间: 2008-8-8 01:28

看完了,云里雾里,不知所谓。。。。。哎。。。
作者: Clark2505    时间: 2008-8-12 17:14

云里雾里,更不明白了。我不需要官方的说明,这个我也找得到。只是看不懂
作者: batman    时间: 2008-8-12 17:30

我来简要说明下:
setlocal就是开启环境变量本地化,其实就是说当开启这个命令后,所有新设置的环境变量
都只在本次运行时有效,而endlocal则是结束环境变量本地化,当然必须先是开启了才会起
作用,当运行endlocal后,先前设置的所有变量将会被清空,示例如下:
  1. @echo off&setlocal
  2. for /l %%i in (1,1,9) do set "_%%i=a"
  3. set _
  4. endlocal
  5. echo.&set _
  6. pause>nul
复制代码

作者: zyc411277063    时间: 2008-11-2 16:45

论坛里就有!!!



【转】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 就不用这么麻烦了。
看代码

@echo off
set var=123
set num=4456
set a=ham
setlocal
set var=abcd
set num=jkl
set a=efg
set max=1234567
::到了这一步,我想不用echo你应该也都知道,这三个变量的值改变了,
::并且还给一个新的变量赋了值 max
::对于不熟悉setlocal 和 endlocal 命令的朋友来说,要想让这
::三个变量回到开始的值,可能就只有回到开头那三句去了,其实不用。
::一句就可以了,看下面的
endlocal
echo %var% %num% %a%
echo %max%
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 的情况。
作者: doupip    时间: 2010-11-1 15:43

了解了,setlocal与endlocal相当于一个局部变量一样,只不过它继承了原来老的变量中的值.
作者: mysuperbat    时间: 2010-11-6 11:39

明白啦,多谢这么详细的解释
作者: wc726842270    时间: 2011-3-5 17:44

不错的文章,用法比较灵活。所以应该不好掌握。
作者: yashuer    时间: 2012-5-26 21:45

if内的endlocal不能结束全局的setlocal
代码如下
@echo off
setlocal enabledelayedexpansion




for /f "delims= tokens=1,*" %%k in (source.mac) do (

if !count!==24  (
endlocal

echo if !num!==8  echo height_num=1-0.%%%%i ^>^>h_%%%%i_s_%%%%j.txt>>ansys_process.bat
                 )

if !count! neq 24 (
endlocal
echo %%k  %%l>>ansys_process.bat
)
echo.>nul
set /a count+=1
)

要测试的source.mac 的内容如下.虽然是批处理的代码
@echo off
setlocal enabledelayedexpansion

set  work_directory=D:\Documents\Desktop\test\


for /f "skip=1 delims=> " %%k in (D:\Documents\Desktop\test\h_1_s_1.mac) do (

if !num!==1   echo /filname
if !num!==2   echo /cwd
if !num!==8  echo height_num=2
if !num!==9  echo speed_num=3

if !num! neq 1  (
if !num! neq 2  (
if !num! neq 8  (
if !num! neq 9 echo test
                 )
echo.>nul
echo.>nul        )
echo.>nul        )
echo !num!
echo.
set /a num+=1


                                                                             )


pause



rem echo it is the end of the code . do not believe you can see it on your screen
作者: yashuer    时间: 2012-5-26 21:48

如果把上面if 内的endlocal去除的话.就得不到正确的结果.同时endlocal不能结束 !count!的替换.
作者: cjiabing    时间: 2012-5-29 20:17

一般你使用到setlocal 或 endlocal 的情况是:
1、变量延迟开关
setlocal   enabledelayedexpansion
开启变量延迟
setlocal   disabledelayedexpansion
关闭变量延迟
2、变量本地化
如:
  1. set v=123
  2. echo %v%
  3. pause
  4. setlocal
  5. set v=abc
  6. echo %v%
  7. pause
  8. endlocal
  9. echo %v%
复制代码
比较下同一个变量在三个情况下的结果。
setlocal和endlocal相当于一个存储临时变量的灌,类似于pushd和popd、echo off 和echo on
作者: muink    时间: 2015-5-31 21:32

就相当于每次setlocal就建立一个沙盘,每次完成运算后endlocal就清除当前沙盘




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