bat脚本-set(setlocal enabledelayedexpansion) 学习
设置本地为延迟扩展。其实也就是:延迟变量,全称延迟环境变量扩展。
事件一:
@echo off
set a=4
set a=5&echo %a%
pause
解说:为什么是4而不是5呢?在echo之前明明已经把变量a的值改成5了。
批处理运行命令的机制:批处理读取命令时是按行读取的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行),在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。我们现在分析一下例1,批处理在运行到这句“set a=5&echo %a%”之前,先把这一句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!(没有为什么,批处理就是这样做的。)而为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值。如何开启变量延迟呢?变量延迟又需要注意什么呢?
事件二:开启 变量延迟机制!
@echo off
setlocal enabledelayedexpansion
set a=4
set a=5&echo !a!
pause
结果:5
解说:由于启动了变量延迟,得到了正确答案。变量延迟的启动语句是“setlocal enabledelayedexpansion”,并且变量要用一对叹号“!!”括起来(注意要用英文的叹号),否则就没有变量延迟的效果。分析一下例2,首先“setlocal
enabledelayedexpansion”开启变量延迟,然后“set a=4”先给变量a赋值为4,“set a=5&echo
!a!”这句是给变量a赋值为5并输出(由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此此时a的值就是5了)。
事件三: (一般通过全局变量保存返回值的比较常见),当前这个示例通过变量传递来保存函数的返回值:
@echo off
::通过给调用者传递一个变量(var),来保存函数的返回值
call :myFunc var
echo.var:%var%
goto :eof :myFunc
set "%1=haha"
goto :eof
结果:var:haha
解说:通过给 myFunc 函数传递 var 一个变量,然后 函数中 通过 set "%1=haha" 给第一个参数设置值,也就是给变量设置;
事件四: 通过 设置局部的可延迟的扩展变量 来实现循环,如下循环5次;
@echo off
::设置局部的可延迟的扩展变量a
setlocal enabledelayedexpansion
for /l %%i in ( 1,1,5 ) do (
set a=%%i echo !a!
)
pause
解释: for /l %%i in(start,step,end) do ;这个循环的语法;每次将循环变量赋值给a,并打印出来;必须要加 setlocal enabledelayedexpansion 这一句,否则 a变量 预处理时没有这个东西,会不打印或者打印 echo是关闭状态;
事件五:处理局部变量和全局变量不冲突;SETLOCAL命令能让处理器当做是局部变量,用ENDLOCAL解除局部变量。
@echo off
:: 怎么保证局部变量和全局变量不冲突,SETLOCAL命令能让处理器当做是局部变量,
:: 用ENDLOCAL解除局部变量。
:: ENDLOCAL 会被自动调用,当批处理执行到文件末尾的时候,即GOTO:EOF。
:: SETLOCAL可以很好的保护函数内与外面的变量不会冲突。 set "var1=i'm goloable var1!"
set "var2=i'm goloable var2!" echo.var1 before:"%var1%"
echo.var2 before:"%var2%"
call :myFunc var2
echo.var1 after:"%var1%"
echo.var2 after:"%var2%"
pause && goto :eof
::传一个参数应用进去
:myFunc
SETLOCAL
set "var1=呵呵呵!"
set "%1=%var1%"
echo.var1 :"local Val1 %var1%"
ENDLOCAL
goto :eof
执行结果:
解释: 可以看到 ,代码中 将 var2 引用通过参数传进去,同时在函数中将var1的变量设置为呵呵呵!,但是函数执行完后, var1,和var2都没有变动(尽管var2是以变量的形式传进去的),他们只有在属于的局部区域,赋值才有效,endlocal 执行后,他们又恢复 全局变量的值了;
事件六:怎么跳过ENDLOCAL的屏障,返回局部变量值?采用”变量扩充“,在SETLOCAL与ENDLOCAL之间的全局变量的值会备份,当退出ENDLOCAL,该值将恢复。让命令处理器来执行ENDLOCAL 和SET命令。
@echo off
:: 返回局部变量
:: 怎么跳过ENDLOCAL的屏障,返回局部变量值?
:: 采用”变量扩充“,在SETLOCAL与ENDLOCAL之间的全局变量的值会备份,当退出ENDLOCAL,该值将恢复。
:: 让命令处理器来执行ENDLOCAL 和SET命令。 set "aStr=Expect no changed,Even if used in function~"
set "var1=Expect changed"
echo.aStr before:%aStr%
echo.var1 before:"%var1%"
call :myFunc var1
echo.aStr after:%aStr%
echo.var1 after:"%var1%"
pause && goto :eof :myFunc
setLocal
set "aStr=Try To Change!"
(ENDLOCAL
set "%1=%aStr%"
)
goto :eof
执行结果:
解释:aStr 变量通过全局变量的形式,在 setlocal 和 endlocal 之间赋值,这个赋值肯定是不会影响外部的aStr的值的,怎样将 这个局部设置的值保存下来?如上代码: 在 setlocal 和 endlocal 之外 ,通过 将这个值设置给 传进来的参数变量、或者另一个全局变量,即可将 该局部变量的赋值保存下来并返回;如上图,var1的值变为了 局部赋值:Try To Change!;
事件七:编写递归函数,Fibonacci函数;让函数局部变量的变换对调用者是可见的,循环调用函数,让变量可重用:
@echo off
:: 编写斐波拉里 函数,用来计算多少以内的斐波拉里数! 递归!
set "fst=0"
set "fib=1"
set "limit=10000" :: fib 传的是引用, 另两个传的是值; fib最后用来返回值
call :feberlalie fib,%fst%,%limit%
echo. The next Fibonacci number greater or equal %limit% is %fib%.
pause && goto :eof :feberlalie
SETLOCAL ::可以利用set /a 进行连续赋值,只要用逗号分开每个变量名就可以了。是下面三行代码的缩写
set /a "Num1=%1,Num2=%2,limit=%3"
:: set /a "Num1=%1"
:: set /a "Num2=%2"
:: set /a "limit=%3" :: 在set /a 计算时,可以省略变量的%号或!号,极为方便。 是带百分号的 加法的缩写
:: set /a "Sum=Num1 + Num2"
set /a "Sum=%Num1% + %Num2%" echo.Num1 :%Num1%
if /i %Sum% LSS %limit% call:feberlalie Sum,%Num1%,%limit%
(ENDLOCAL
IF "%1" NEQ "" SET "%1=%Sum%"
)
goto :eof
执行结果:
总结:定义一个标准的dos batch script function(ps:人家总结的不错,直接拿来用了):
:myFunctionName -- function description here 函数名
:: 参数描述 -- %~1: argument description here 下面都是函数体
SETLOCAL
REM.--function body here
set LocalVar1=...
set LocalVar2=...
(ENDLOCAL & REM -- RETURN VALUES 待返回的值
IF "%~1" NEQ "" SET %~1=%LocalVar1%
IF "%~2" NEQ "" SET %~2=%LocalVar2%
)
GOTO:EOF
学习参考链接:
http://blog.csdn.net/xiaoding133/article/details/39252357
http://www.jb51.net/article/29323.htm
bat脚本-set(setlocal enabledelayedexpansion) 学习的更多相关文章
- 360极速浏览器极速模式通过hosts文件切换兼容模式bat脚本
注意:需要获得管理员权限执行,且后缀为 .bat @echo offsetlocal enabledelayedexpansionset url=被替换的域名set ip=替换的域名set strNe ...
- bat脚本基础教程
bat脚本就是DOS批处理脚本,就是将一系列DOS命令按照一定顺序排列而形成的集合,运行在windows命令行环境上.本文主要介绍bat脚本基础语法,希望完成本文内容学习之后具备基础的bat脚本开发能 ...
- windows中实现python,redis服务自动重启(任务计划程序+bat脚本)
需求:银行电脑无法自动开机,只能 通过 应用相关服务每天自动重启的方式实现 服务更新并且防止服务假死,内存过大 等情况 相关工具:win10系统中,使用windows自带的任务计划程序 和 bat脚本 ...
- 【转贴】bat脚本基础教程
bat脚本基础教程 https://www.cnblogs.com/linyfeng/p/8072002.html 自己动手太少了. bat脚本就是DOS批处理脚本,就是将一系列DOS命令按照一定顺序 ...
- Bat 脚本学习 (基础篇)
[转]Bat 脚本学习 2015-01-05 14:13 115人阅读 评论(0) 收藏 举报 基础部分: ============================================== ...
- 今天我自己第一次写了一个Windows批处理bat脚本,一起学习一下吧。
今天我自己第一次写了一个Windows批处理bat脚本,备注一下 事情原由:自己使用Java开发了一个加解密的工具.但是当把工具给别人使用的时候,别人还需要把代码编译打包, 然后还需要看一下代码里面的 ...
- bat脚本学习
工作需求,写个bat脚本来启动自己的守护进程:bat方面完全空白啊~稍微学习了下,记录下来,后面复习! 直接上代码: 示例一:for字符串切割,切割文本中的字符串: test.txt 文本内容如下: ...
- bat脚本参数 if goto choice for使用的学习笔记。
写过几次bat脚本,但一直没有总结,最近找到一个网页介绍bat,总结得很好,转自 http://www.jb51.net/article/49627.htm: 本文只总结我不会的,全面的看原网页就可以 ...
- .bat脚本基本命令语法
目录批处理的常见命令(未列举的命令还比较多,请查阅帮助信息) 1.REM 和 :: 2.ECHO 和 @ 3.PAUSE 4.ERRORLEVEL 5.TITL ...
随机推荐
- C++ multimap容器访问同一键值元素的不同方法
multimap是一种多元map容器,允许一个键对应多个值. 本文介绍了 multimap访问同一键值元素的三种不同方法,详细看下面代码: typedef multimap<string,int ...
- java web项目基础
listener,filter,servlet的初始化顺序 web.xml中可以配置如下信息: context-param,listener,filter,servlet. 他们的加载顺序和在we ...
- D10
=-=今天被dev-c++坑到死..简直 晚上准备怒装liunx.. T1:数论 一开始碰到的是T1的运算符优先问题吧..maybe..但是我加上括号了还是WA啊..后面把式子拆开写才A了..次奥 附 ...
- VMware NAT方式 CentOS 6.8配置静态IP
一.打开虚拟机设置,配置网络连接,如下图 二.编辑 /etc/sysconfig/network,以配置网关 vim /etc/sysconfig/network NETWORKING=yes HOS ...
- (转)cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行)转载请保留作者信息:1.cin1 ...
- Silverlight类百度文库在线文档阅读器(转)
百度文库阅读器是基于Flash的,用Silverlight其实也可以做. 我实现的在线阅读器可以应用于内网文档发布,在线阅览审批等.没有过多的堆积功能,专注于核心功能.主要有以下特性: 1. 基于XP ...
- cocos2d-x C++的do...while(0)另类使用方法
在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视. 但是 ...
- Django 中的 WSGI
Django 源码小剖: Django 中的 WSGI 2013-09-06 22:31 by 捣乱小子, 334 阅读, 0 评论, 收藏, 编辑 Django 其内部已经自带了一个方便本地测试的小 ...
- Google开源的Deep-Learning项目word2vec
用中文把玩Google开源的Deep-Learning项目word2vec google最近新开放出word2vec项目,该项目使用deep-learning技术将term表示为向量,由此计算te ...
- go语言中的数组切片:特立独行的可变数组
go语言中的数组切片:特立独行的可变数组 初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多.但是在使用了一段 ...