由batch 命令setlocal enabledelayedexpansion引发的

简介: <p>预告:先来一段长长的唠叨!</p> <p>作为一名比较能折腾的初级程序员,对一切都充满了好奇心,强迫症是个比较流行的词,我想我也应该是中毒份子吧。</p> <p>这几天在公司折腾环境,一直用的是ubuntu,很好很强大,但是用上两个显示屏后就变得特别慢(绝对无法忍受),ubuntu10.10后一直采用的事unity桌面,后来在google上发现原来是个bug(<a target=

预告:先来一段长长的唠叨!

作为一名比较能折腾的初级程序员,对一切都充满了好奇心,强迫症是个比较流行的词,我想我也应该是中毒份子吧。

这几天在公司折腾环境,一直用的是ubuntu,很好很强大,但是用上两个显示屏后就变得特别慢(绝对无法忍受),ubuntu10.10后一直采用的事unity桌面,后来在google上发现原来是个bug(https://bugs.launchpad.net/ubuntu/+source/unity/+bug/769650),无奈,解决方案也不好,于是转向gnome,gnome3我不喜欢,感觉不方便,ubuntu10.04采用的gnome2才是王道,google后发现gnome2这个项目已经死了(呜呜~~),不过开源世界总是有你想不到的,一个新的项目mate继续开发gnome2,很happy,安装方式也很简单,见http://wiki.mate-desktop.org/download。晒一下


左面写程序,右面看文档,爽多了!

---------------------------------------------很高兴你能看到华丽的分割线,下面进入正题--------------------------------------------------------------------------------------------------------------------------

在电脑变快之后,装上了vb,然后想装个绿色版qq,网上JayXon的应该是最普及的,他这里面有个bat文件,以前也没想着去打开看看,今天突发奇想打开看了看,发现是个很神奇(其实是micorsoft比较笨吧)的代码:

SetLocal EnableDelayedExpansion
网上发现这叫 延迟环境变量扩展,很奇怪的名字,这是什么回事呢,google一番后发现是这么回事:

batch文件在执行时,解释器会把先把一整条命令读入,然后分析语法是否正确,这在单句是没有任何问题的,但是bat文件中的if、for等这些符合语句(符合也算一个语句)就有问题了,下面我一一以代码演示之。下面的代码写在C:\hello.bat文件中,读者可以copy自行实践之。

@echo off
set foo="helloworld"
echo %foo%

上面是很简单的单句赋值情况,程序能够程序正确输出helloworld

下面看看如果是if语句会怎么样呢?

@echo off
set foo="helloworld"
if %foo%=="helloworld" (
	set foo="helloubuntu"
	echo %foo%
)
这时程序会输出什么呢?不了解batch文件的人肯定说是helloubuntu了,但是事实却还是helloworld,这是为什么呢?

现在我请你换下身份,以batch解释器而不是程序员的思路来看这个脚本到底是怎么执行的:

1.首先,解释器看到if后知道这条语句是个符合语句,那么他会读取一个完整句子后在进行后面的语法验证、执行(读整个句子时并不执行)等操作

2.读完整个句子后,解释器会进行一项变量扩展(也就是我们熟知的变量替换)的工作,batch特有的语法是两个%之间的变量(上面的%foo%就是)会被替换

3.完成替换工作后,解释器开始执行这个整句。

在上面3个过程后,解释器看到的是这样的代码:

@echo off
set foo="helloworld"
if %foo%=="helloworld" (
	set foo="helloubuntu"
	echo "helloworld"
)
所以,这么一看,输出helloworld一点也不奇怪了。

为了加深大家的理解,我在给一个for的例子

@echo off
for /L %%i in (1,1,10) do (
     set foo=%%i
     echo %foo%
)
这会输入什么呢,看看结果

为什么会这样呢?读者可以试着吧编译器看到的结果自己写出来,其实也很简单

@echo off
for /L %%i in (1,1,10) do (
     set test=%%i
     echo  
)
就是这样的嘛,那么为什么会是上面的信息呢,这里你需要了解echo命令的用法,如果你只输入一个echo,后面不跟任何参数,那么将输出echo的状态


通过echo的帮助文档我们可以很清楚的了解,同时对于batch能够识别的命令都能够用类似的语法获得

因为我们第一行的@echo off将echo的状态给关闭了,所以输入了如上的信息。

到现在位置我们已经知道了batch解释器在解释符合语句时的问题了,那么微软时如何解决的呢,其实我们自己想想也很好相出办法解决,你一行行的读入不就行了嘛,干嘛非要读入符合语句的整句。其实微软也是这么做的,这就是本文标题命令的由来了,不过这是为了要用!变量名!的形式来引用了。 

我们这次把上面的两个例子加上setlocal enabledelayedexpansion再试试看:

首先是if的情况

@echo off
setlocal enabledelayedexpansion
set foo="helloworld"
if %foo%=="helloworld" (
	set foo="helloubuntu"
	echo !foo!
)

for的那个例子:

@echo off
setlocal enabledelayedexpansion
for /L %%i in (1,1,10) do (
	set foo=%%i
	echo !foo!
)

结果和我们预想的一样了。







目录
相关文章
解决Mybatis-Plus更新对象时为法将某字段更新为空值的问题
解决Mybatis-Plus更新对象时为法将某字段更新为空值的问题
解决Mybatis-Plus更新对象时为法将某字段更新为空值的问题
|
7月前
|
存储 弹性计算 缓存
阿里云服务器ECS经济型、通用算力、计算型、通用和内存型选购指南及使用场景分析
本文详细解析阿里云ECS服务器的经济型、通用算力型、计算型、通用型和内存型实例的区别及适用场景,涵盖性能特点、配置比例与实际应用,助你根据业务需求精准选型,提升资源利用率并降低成本。
504 3
|
7月前
|
存储 调度
微信自动评论朋友圈,微信朋友圈自动发布工具,定时发朋友圈脚本
这个实现包含完整的微信朋友圈自动发布功能,支持定时发布、多图发布、任务持久化存储等功能
|
JavaScript API 开发者
vue自定义Hooks函数使用和封装思想
【8月更文挑战第8天】vue自定义Hooks函数使用和封装思想
569 1
|
10月前
|
小程序 Java 关系型数据库
weixin049校园外卖平台设计与实现+ssm(文档+源码)_kaic
本文介绍了一款校园外卖平台的设计与实现过程。该平台采用Java的SSM框架进行后台管理开发,使用MySQL作为本地数据库,并通过微信小程序为用户提供便捷的操作界面。系统包括管理员、用户和商家三个角色,功能涵盖个人中心、用户及商家管理、菜品分类与信息管理、订单处理等。管理员可在浏览器上登录管理后台数据,用户与商家则通过微信小程序注册登录,分别实现订餐与菜品管理功能。此平台具备界面清晰、操作简单、功能齐全的特点,有助于提升校园外卖管理的效率与规范性。
|
存储 缓存 Java
dex、vdex、.odex与.oat
dex、vdex、.odex与.oat
1229 8
|
弹性计算 开发框架 .NET
阿里云服务器购买教程及云服务器地域、实例、操作系统、带宽等参数选择指南
对于初次购买阿里云服务器的用户来说,想使用阿里云服务器搭建网站或者运行APP、小程序等项目,第一步就是要先购买阿里云服务器,下面小编以图文形式给大家介绍一下阿里云服务器的购买流程,以及购买过程中如何云服务器地域、实例、带宽等关键配置和选择这些参数的一些注意事项,以供参考。
|
弹性计算
新手必看,阿里云国际购买服务器带宽如何选择
新手必看,阿里云国际购买服务器带宽如何选择
|
消息中间件 网络协议 Kafka
Kafka【付诸实践 02】消费者和消费者群组+创建消费者实例+提交偏移量(自动、手动)+监听分区再平衡+独立的消费者+消费者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka消费者】
【2月更文挑战第21天】Kafka【付诸实践 02】消费者和消费者群组+创建消费者实例+提交偏移量(自动、手动)+监听分区再平衡+独立的消费者+消费者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka消费者】
670 3
|
Java 容器 Spring
Javaweb之SpringBootWeb案例之 Bean管理的获取Bean详细的解析
Javaweb之SpringBootWeb案例之 Bean管理的获取Bean详细的解析
426 0

热门文章

最新文章