zoukankan      html  css  js  c++  java
  • 延迟环境变量扩展(bat)

    %var%相当于宏变量直接将值换到命令中,然后执行。

    !var!则是普通变量,每次可以直接读取内存中的值。

    延迟变量全称\"延迟环境变量扩展\",要理解这个东西,我们还得先理解一下什么叫扩展!
        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.

    @echo off
    setlocal ENABLEDELAYEDEXPANSION
    IF "%1"=="" (
    echo "aaa"
    ) ELSE (
    set hour=%1
    set /a smallhour=hour-1
    echo !hour!
    echo !smallhour!
    if "%time:~0,5%" geq "%smallhour%:45" if "%time:~0,5%" leq "%hour%:15" echo "aaa"
    )

  • 相关阅读:
    合肥程序员欢迎进QQ群49313181同城程序员职业交流群
    新一代程序员的思考
    ThinkPHP开发系列一框架搭建
    ASP.NET MVC4+EF系列之五 架构介绍
    ASP.NET MVC4+EF系列之阶段源码一
    gcc g++ Linux下动态库_静态库 指定路径问题
    [转]accept() 产生的Socekt端口是多少?
    阿里云计算资深总监唐洪:飞天大规模分布式计算系统解析
    [转] C++中##(两个井号)和#(一个井号)用法
    deep learning 深度学习
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/2671218.html
Copyright © 2011-2022 走看看