Chinaunix首页 | 论坛 | 博客
  • 博客访问: 102663
  • 博文数量: 32
  • 博客积分: 151
  • 博客等级: 入伍新兵
  • 技术积分: 225
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-11 16:18
文章分类

全部博文(32)

文章存档

2014年(27)

2013年(5)

我的朋友

分类: LINUX

2013-11-13 00:20:32

看这样一个批处理,迭代显示1到20:







::示例1


@echo off
for /l %%i in (1 1 20) do echo
%%i
pause




  这个很简单,那么如果我们不用 %%i 来显示,而启用一个新的变量名 hanye 呢?








::示例2(错误)


@echo off
for /l %%i in (1 1 20) do (
set
hanye=%%i
echo %hanye%
)
pause




  运行结果并没有显示1到20,而是显示:ECHO 处于关闭状态。我们知道,出现这个显示,是因为
echo 后面什么也没有,如果跟了变量,则变量为空。那么,为什么变量为空了呢? set hanye=%%i 不是为变量赋值了吗?通过示例1,我们也知道 %%i 确实获得了数值。


  在这里,我们要引入一个重要的概念——预处理机制:批处理读取命令时是按行读取的(另外例如 for
命令等,其后用一对圆括号闭合的所有语句也当作一行),在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。在不启用变量延迟,也不对变量动态捕获其扩展变化时,变量在预处理阶段不作改变。


  现在,我们看示例2:在 set hanye=%%iecho %hanye% 之前,不存在变量 hanye
,即为空。而 set hanye=%%i 是在更改变量 hanye 的数值,这个更改在这一整句完成前不会生效。但 echo
%hanye%
却又处在生效完成前,即包括在预处理这一句的内部,所以无法显示新获取的值,就显示原来的值——空。


  如果将 echo %hanye% 放在预处理之后,即 ) 的下面,我们就会看到 %hanye%
的数值,当然,这个时候只显示5。




  回过头来,我们看示例1和示例2,变量 %%i 的数值由 for 直接赋值,在预处理时,%%i 的值并没有变化。


  我们将示例2改成这样,就可以正常显示了:








::示例3


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (1 1 20) do (
set hanye=%%i
echo
!hanye!
)
pause




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 命令或者到达批处理文件的结尾时将恢复上一次的设置。


  • 在批处理程序中可以包含多个 setlocalendlocal 命令(嵌套)。
  • 测试批处理文件中的命令扩展

    setlocal 命令设置 ERRORLEVEL 变量。如果遇到 {enableextension |
    disableextensions} 或 {enabledelayedexpansion |
    disabledelayedexpansion},ERRORLEVEL 变量将设置成 0 (0)。否则,该变量将被设置成 1
    (1)。在批处理脚本中使用该命令可以确定扩展是否可用,例如:


     verify other 2>nul setlocal enableextensions if errorlevel 1 echo Unable to enable extensions 


    因为当禁用命令扩展时 cmd 不会设置 ERRORLEVEL 变量,所以当通过无效参数使用 setlocal 命令时
    verify 命令将 ERRORLEVEL 变量初始化为非零值。另外,如果通过 {enableextension |
    disableextensions} 或 {enabledelayedexpansion |
    disabledelayedexpansion} 参数使用 setlocal 命令,而且没有将 ERRORLEVEL 变量设置成 1
    (1) 时,则命令扩展将不可用。




Endlocal:




  结束批处理文件中环境更改的本地化,将环境变量还原为匹配 setlocal 命令前的值。



语法



endlocal



参数




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


注释




  • 必须在脚本或批处理文件中使用 endlocal。如果在脚本或批处理文件之外使用 endlocal,则该命令无效。
  • 在批处理文件的结尾处有一个隐含的 endlocal 命令。
  • 通过启用命令扩展名(即,默认值),endlocal 命令将命令扩展名的状态(即,已启用或已禁用)还原到执行匹配
    setlocal 命令之前的状态。



启用延迟的环境变量扩展:




  setlocal enabledelayedexpansion
,就是启用变量延迟,我们可以形象的认为是启用了“对变量动态捕获扩展变化”。而 !
括起来的变量,就是要动态捕获扩展的目标变量,如果不需要,可以继续使用 % 括变量。


  那么,什么情况下需要启用变量的延迟呢?在复合语句中,一旦变量需要发生扩展变化,就需要启用。


  我们看一下示例4:








::示例4


@echo off&setlocal
enabledelayedexpansion
set han=1
set han=2 &echo
!han!
pause




  在预处理这一复合句时, set han=2
将在完成这一句时才生效。在没有完成这一句时,变量 han
的数值依然是1。现在,我们来看一个复杂点的复合句:








::示例5 显示数列01-20,并使用if判断


@echo off
for /l %%i in (1 1 20) do if %%i lss 10
(echo 0%%i) else echo %%i
pause




  当 for 在第一次循环时,为 %%i 赋值为1,其后的 if %%i 时,使用的依然是这个数值;在 echo 0%%i
时也依然用1这个数值;在 echo %%i 时,还是用1这个数值。在整个预处理这一整句的过程中,
%%i 并没有发生变化,所以不需要变量延迟以动态扩展。现在,我们来他另一个批处理示例:








::示例6 显示数列01-20,并使用set补0


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (1 1 20) do (
set han=0%%i
echo
!han:~-2!
)
pause




  在这一示例中,%%i 依然不需要动态变量扩展,因为他在预处理时不发生变化,但变量 han 则不同,他从空变成了有数值,发生了变化,所以需要变量延迟并动态扩展他。




关于 %%i :




  需要说明一个问题,%%i
是可以被作为普通变量名使用的,上面的示例6就可以写成如下示例7:








::示例7


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (1 1 20) do (
set %%i=0%%i
echo
!%%i:~-2!
)
pause




  但是,%%i 做为变量使用,并作为截取、替换、运算等时的变量名,仅限于为其赋值的 fordo ()的内部。


  那么, set %%i=0%%iecho !%%i:~-2! 可以用 &
连接起来吗?可以的,但问题也出来了,如下示例8:








::示例8(错误)


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (1 1 20) do set %%i=0%%i & echo
!%%i:~-2!
pause




  运行后,仅显示一列的一位数字,那么那另一列的一位数哪去了呢?我们把 echo !%%i:~-2!
改成 echo !%%i:~-3! 就可以看到了。问题出在哪了呢?原来,当 set 与其他命令用 &
连接起来的时候,中间是不能有空格的,否则 set
会把空格当做给变量所赋的值的一部分。所以,示例8的正确写法如下:


示例9:








::示例9


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (1 1 20) do set %%i=0%%i&echo
!%%i:~-2!
pause




  凡事皆有例外, set%%i
也是如此。也就是说,不能有这样的表但式: set /a %%i=%%i+10%%i 不能在 set /a
中做设置的变量名,否则提示错误“运算符不存在。”。必须写成: set /a
hanye=%%i+10
。如下示例:迭代-3到1(步长为1),并将每个结果再加10,然后为1-9前补0。








::示例10


@echo off&setlocal enabledelayedexpansion
for /l
%%i in (-3 1 1) do (
set /a hanye=%%i+10
set %%i=0!hanye!
echo
!%%i:~-2!
)
pause



阅读(1511) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:linux重定向及nohup不输出的方法

给主人留下些什么吧!~~