zoukankan      html  css  js  c++  java
  • dos中的延迟环境变量扩展

    一、前言

    昨天在写bat脚本的时候,发现在for里面的set命令竟然不起作用!于是搜了一下,前面的几篇都有说到这个是变量扩展的问题,但是什么是变量扩展?为什么会出现这种问题,什么又是延迟环境变量扩展?则说得不明不白。那些文章里给的解决方案,试过了一下甚至无法起作用。可怕的是那篇文章其他人还复制了。

    还好今天搜了一下,看到一篇能真正说明并解决这个问题的,于是决定整理如下。

    二、变量扩展

    变量扩展对应现在高级程序语言中的变量赋值,batch文件在解释的时候,首先会读取命令行一条完整的命令,然后对其进行一些命令格式的匹配操作,看所输入的命令格式是不是符合它的要求。

    如果我们要在我们的命令中引用一些变量,那么我们就可以在变量名字两边加一个%号, 如%name%。当CMD在对读取我们的整行命令进行格式匹配的时候,就会发现name这个字符两边加了%号,就不会把他当作普通字符处理,而是会当作一个变量处理,变量名叫name,然后找到变量名对应的值替换掉这个变量名字(name),再将这个替换好并且匹配的命令执行。这个替换值的过程,就叫做变量扩展,这个过程简单点来说就是:

    1. 读取一个完整的命令并进行语法检查。

    2. 将%变量名%替换成变量内容

    3. 执行这个命令。

    对于单句是没什么问题,但是像if和for以及&复合语句时就会出现一些奇怪的现象,如以下语句:

    @echo off
    set x=22
    set x=33 & echo %x%
    pause

    输出不是期望的33,而是22。按照上面说的变量扩展过程,实际上解释器看到的代码是这样的:

    @echo off
    set x=22
    set x=33
    echo 22
    pause

    为了解决这个问题,于是微软引入了“延迟环境变量扩展”的机制。

    三、延迟环境变量扩展

    延迟环境变量扩展,即每条指令在执行之前才将变量进行替换,以保证对变量的任何修改都可以实时生效。

    在批处理中,我们可以用setloacl enabledelayedexpansion这个命令来启用"延迟环境变量扩展",启用之后,解释器会用!号来判断这是不是一个变量。

    于是上面的脚本可以改为:

    @echo off
    setlocal enabledelayedexpansion
    set x=22
    set x=33 & echo !x!
    pause

    四、参考

    1. 百度百科:延迟环境变量扩展

    2. 延迟环境变量扩展(bat)

  • 相关阅读:
    关于换行
    WebService
    C#操作XML的通用方法总结
    19个必须知道的Visual Studio快捷键
    Asp.net C# 把 Datatable转换成JSON 字符串
    C#中的多态性
    virtual和abstract
    DataTable的过滤需要的数据
    自定义控件之瀑布流与水波纹实现
    反转链表
  • 原文地址:https://www.cnblogs.com/harrymore/p/8931590.html
Copyright © 2011-2022 走看看