先来说说变量延迟扩展吧。当然,放狗一搜,就能看到满天飞的关于变量延迟扩展的文章,所以,我这里就简单介绍一下。先来看一段批处理:

set str=test

if %str%==test (
set str=another test
echo %str%
)

  

上面的代码段极其简单,给str赋值,判断其值是否为test,如果是,重新赋值为another test,再显示str的值。

作为正常人的思维,这里显示的肯定是another test了,但其实不是,其显示的仍然是test,这是为什么?因为:windows在解释执行此代码段时,在遇到if语句后的括号后,只把它当一条语句处理而不是两条语句,所以,在第二条语句中的%str%会被替换成它目前的值test,上面的代码相当于下面的代码的效果:

set str=test

if %str%==test (
set str=another test
echo test ::注意这里
)

  

所以,输出自然是test了。

这样编程的灵活性就大大降低了,于是,M$就想了一个workground的方法,那就是变量延迟,很简单,看如下代码:

@echo off
setlocal enabledelayedexpansion ::注意这里 set str=test if %str%==test (
set str=another test
echo !str! ::注意这里
echo %str% ::区别
)

  

现在会输出什么呢?试一下就知道,第一行输出another test,第二行输出test。

现在解释一下, setlocal enabledelayedexpansion 用于开启变量延迟,这是告诉解释器,在遇到复合语句的时候,不要将其作为一条语句同时处理,而仍然一条一条地去解释。但是这时必须用!str!来引用变量,如果仍然用%str%引用是不起作用的。

好了,变量延迟扩展解释完了,至少这就是我知道的变量延迟扩展。


今天变量延迟扩展和感叹号让我蛋疼了半天,所以现在也要来扯扯它们的蛋。

试试以下代码段:

@echo off

setlocal enabledelayedexpansion

set str=test!!!

echo %str%

  

开启变量延迟,给str赋值,输出str,于是,输出自然是test!!!了。但其实,windows告诉我们,又错了,输出是test,感叹号被windows吃了。

当然如果注释掉开启变量延迟那一行,这几行是可以正常工作的,所以说是开启变量延迟影响了我们正常的工作,但我至今还没搞清楚为什么会这样,这只有M$知道。

于是,关闭变量延迟吧,可是程序又需要使用变量延迟来实现一些逻辑,怎么办?两个办法:

  1. 暂时关闭变量延迟:

    @echo off
    
    setlocal enabledelayedexpansion
    
    :: do something here
    
    setlocal disabledelayedexpansion    ::关闭变量延迟
    
    set str=test!!!
    
    echo %str%
    
    setlocal enabledelayedexpansion
    
    :: continue...
    

      

    在需要处理感叹号的地方,暂时关闭变量延迟,处理完后再打开。这时能正常输出感叹号。

  2. 在开启变量延迟之前set:

    @echo off
    
    set str=test!!!
    
    setlocal enabledelayedexpansion
    
    echo !str!    ::注意这里
    

      

    在开启变量延迟之前设置好变量,但是要注意,在使用变量的时候,需要使用感叹号引用。这时感叹号也可以正常输出。


最后贴一段为什么让我蛋疼的代码(变量延迟自然是打开的):

set server=%~1
set username=%~2
set password=%~3
echo %date%, %time% [INFO] Report server address: [%server%], username: [%username%], password: [*******] rs.exe -i "PublishReports.rss" -s "%server%" -u "%username%" -p "%password%" -l 600

  

为了不回显password,我输出了一大串*。在我机器上测试时,我的password字符都很常规,所以通过。但是,QA的password里面有感叹号。。。

关键的是,这里调用的是M$的Report Server的rs.exe来上传模板,它抛出一个Could not connect的exception,于是,我自然地想到是report server的service出了问题,但查了好久也没发现report server有什么问题。。。谁TMD会想到是别人的password里有感叹号,谁TMD又会想到是跟所谓延迟变量的冲突导致的,更有谁会想到,我自己自作聪明地为了不显示password而显示出了一大串hard code的星号导致看不到password的值。。。

原文链接:

https://kelvinh.github.io/blog/2012/02/16/batch-delayed-expansion/

cmd enabledelayedexpansion的更多相关文章

  1. win7 winsxs精简 cmd 脚本之 再次 改进版

    dos时代菜鸟发表于 2012-7-24 http://bbs.wuyou.net/forum.php?mod=viewthread&tid=255200&highlight=win7 ...

  2. cmd命令行中的errorlevel和延迟赋值

    最近用到了命令行,一点心得: 1.errorlevel返回的确实是上一条命令的返回值,但不同命令的表现完全不同.比如: dir echo %errorlevel% //显示0 dir aldkalf ...

  3. BAT CMD 批处理文件脚本 -2

    http://checheng1988.blog.51cto.com/4725808/1090733 在很多windows程序中会见到很多用扩展名为.bat和.cmd结尾的文件,那么这些文件能干什么呢 ...

  4. BAT CMD 批处理文件脚本 -1

    http://www.cnblogs.com/linglizeng/archive/2010/01/29/Bat-CMD-ChineseVerion.html 1.               综述 ...

  5. Windows批处理(cmd/bat)常用命令小结

    转载自:“趣IT”微信公共号 前言 批处理文件(batch file)包含一系列 DOS命令,通常用于自动执行重复性任务.用户只需双击批处理文件便可执行任务,而无需重复输入相同指令.编写批处理文件非常 ...

  6. setlocal enabledelayedexpansion

    http://www.jb51.net/article/29323.htm 例1: 代码如下: @echo off set a=4 set a=5&echo %a% pause  结果:4 解 ...

  7. 转 BAT CMD 批处理文件脚本总结(中文)

    1.               综述 1.”.bat”: 这是微软的第一个批处理文件的后缀名,在几乎所有的Windows 操作系统内都能运行. 2. “.cmd”: 是为Windows NT 设计的 ...

  8. cmd实现批量文件的base64加密并双击加密文件后正常运行

    之前,一个朋友让我用cmd做个简单的文档加密(base64),对于不太懂电脑的人来说看不懂就行.但是当那个人点击加密后的文件可以正常运行,问咋写? 其实,像这种要求不高的加密来说,随便下载个加密软件就 ...

  9. cmd的变量总结

    转自:https://blog.csdn.net/flyoutsan/article/details/52811095 cmd变量通过set设置变量,通过可以使用set /?查看有关变量的帮助文档. ...

随机推荐

  1. Kibana 基础入门

    原文地址:Kibana 基础入门 博客地址:http://www.extlight.com 一.前言 Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作.Kibana ...

  2. BASIC-2_蓝桥杯_01字串

    问题描述 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能.它们的前几个是: 请按从小到大的顺序输出这32种01串. 输入格式 本试题没有输入. 输出格式 输出32行,按从小到大的顺 ...

  3. python 用到的函数记录

    1. ctime() 获取当前的时间 2. import  random random.randint(0,99) 随机产生0到99之间的数值 (包含0和99) (整数!!) 3. 往列表添加数值 l ...

  4. [转]Oracle 中计算时间间隔的SQL 语句

    ' second as TSec from dual -- 计算 60秒 前的时间 ' minute as TMin from dual -- 计算 10分 前的时间 ' hour as UTCTim ...

  5. java study2

    Intellj小技巧 数组 1.java数组元素类型是唯一的,即一个数组只能存储一种数据类型的数据,而不能存储多种数据类型的数据. 2.java数组的长度,一旦初始化完成,控件就被固定,即数组的长度将 ...

  6. sentinel服务器出现大量的连接问题【转载】

    一.问题现象 redis服务端的sentinel模块存在大量的established状态的连接,并且这些连接一直不被释放,而客户端的连接数正常. 二.问题排查过程 1.根据连接状态进行推断 服务端存在 ...

  7. MySQL 特殊参数

    ###开发规范 开发规范:关键字大写,库名字小写,要有字符集 CREATE DATABSE oldboy CHARSET utf8;    ###建议采用第一种 CREATE DATABSE oldb ...

  8. django中视图处理请求方式(FBV、CBV)

    FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...

  9. 「CQOI2016」K 远点对

    /* 考虑暴力 可以n ^ 2枚举点对 然后用一个容量为2k的小根堆来维护第k大 kd-tree呢就是来将这个暴力优化, 每次先找远的并且最远距离不如堆顶的话就不继续找下去 貌似挺难构造数据卡的 */ ...

  10. Executor框架(四)周期/延时任务ScheduleThreadPoolExecutor

    ScheduledThreadPoolExecutor 介绍   ScheduledThreadPoolExecutor 是一个可以实现定时任务的 ThreadPoolExecutor(线程池).比 ...