批处理中的变量
批处理中的变量包括“系统变量”和“自定义变量”。
批处理与其他语言特别是编译语言比较大的不同是,他的变量环境是和本地计算机共享的,包括缺省的计算机信息相关变量,windows中设置的环境变量,和自己定义的自定义变量。而自定义变量也可以有很多来源,可以设置,可以通过参数获得,也可以让用户输入,现在让我们详细了解下。
系统变量:
系统变量的值,是由系统根据事先条件自动赋值的,也就是说,系统已经给他们命名和赋值,我们只需要直接使用就可以了
例如:
%DATE% - 返回当前日期
%USERNAME% - 返回当前用户名
%JAVA_HOME% - 返回环境变量里设置的“JAVA_HOME”的值。
Q.我可以修改这些变量的值么,在我的批处理程序里,比如我想修改JAVA_HOME
A.是的,你确实可以这么做,而且许多程序也需要通过这样来修改“环境变量”中的值,比如Path或者classpath来帮助启动应用程序,但是需要注意的是,这些环境变量并没有被永久的修改,而只是在当前的批处理进程中被赋予了新的值,其它进程并不会被次修改所影响,进程结束后也无法获得修改后的值,而是显示实际值。
另外还有一种变量也被称为系统变量,他们代表一个意思或者一个操作,包括:
%0 %1 %2 %3 %4 %5 …… %9 和 %*
% 1 ~ %9 - 用来返回批处理的第一到第九个参数,是的,只能有 9 个参数,没有 %10 或者 %99 。例如你可以写这么一个批处理:
@echo off
echo %1=====%2=====%3
pause
然后这么启动它:
test.bat 第一个参数 第二个参数 第三个参数
%* - 他会一次返回所有参数,而不是一个个的赋值
%0 – 这个比较重要,他有两个意思,第一个,他会返回当前批处理所在绝对路径,例如:
echo %0
这会返回例如“C:\Documents and Settings\Administrator\桌面\test.bat”这样的结果
另外一个意思,是无限循环执行当前批处理例如:
net user
%0
程序会无限执行下去,直到你手动停止它。
自定义变量:
故名思意,自定义变量就是由我们来给他赋予值的变量
要使用自定义变量就得使用set命令了,看例子:
@echo off
set var=我是值
echo %var%
pause
保存为BAT执行,我们会看到CMD里返回一个 "我是值"
var为变量名,=号右变的是要给变量的值
如果我们想让用户手工输入变量的值,而不是在代码里指定,可以用用set命令的/p参数,例如:
@echo off
set /p var=请输入变量的值
echo %var%
pause
var变量名 =号右边的是提示语,不是变量的值
变量的值由我们运行后自己用键盘输入!
让我们详细说明下set命令,他可不是只有那么弱鸡的功能,让我们来看下set的具体功能:
显示、设置或删除 cmd.exe 环境变量。
SET [variable=[string]]
variable 指定环境变量名。
string 指定要指派给变量的一系列字符串。
要显示当前环境变量,键入不带参数的 SET。
好吧,我骗了你,你确实没看错,其实所有变量都是环境变量,但是他们都只在当前进程中可以被定义和修改,进程间是独立的。
然后你还需要注意两点,第一,set命令是不允许变量名里有等于号(=)的。
第二,set variable=,这条命令相当于清除variable的值,使其成为未定义状态,而set variablue=“”并不是为空,而是使其值变为两个引号,这和一些编译语言是不同的,不是变成空字符串。
通过set,我们不仅能设置变量,改变他们的值,还能对他们进行一些列处理,让我们来看看该如何做。
1.通过set进行数值计算:
语法:SET /A expression
/A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式评估器很简单并以递减的优先权顺序支持下列操作:
() -分组
! ~ - -一元运算符
* / % -算数运算符
+ - -算数运算符
<< >> -二进制逻辑移位
& -二进制按位“与”
^ -二进制按位“异”
| -二进制按位“或”
= *= /= %= += -= -算数赋值
&= ^= |= <<= >>= -二进制运算赋值
, -表达式分隔符
来个例子会比较直接些:
set aa=0930
set /a aa=1%aa%-10000
echo %aa%
显示的结果是930
这里就要说到批处理的一个机制,就是预处理。
程序执行“set /a aa=1%aa%-10000”其实是这么工作的,首先使用aa=0930来为这条语句赋值,语句变成了“set /a aa=10930-10000”,然后在进行数值计算,得到“10930-10000=930”,再把这个值,赋值给aa。
详细内容会在后面说明,这里剧透一下。
让我们做个小程序设法了解更多:
@echo off
set /p input=请输入计算表达式:
set /a var=%input%
echo 计算结果:%input%=%var%
pause
请输入计算表达式:-2147483648-1
计算结果:-2147483648-1=2147483647
另外还有一些用逻辑或取余操作符,这些符号,按照上面的使用方法会报错的
比如我们在CMD里输入set /a var=1 & 1 "与运算",他并不会显示为1,而是报错,
为什么?对于这样的"逻辑或取余操作符",我们需要把他们用双引号引起来,也可以用转义字符^,看例子
set /a var= 1 "&" 1 这样结果就显示出来了,其他逻辑或取余操作符用法
set /a var= 1 "+" 1 异运算
set /a var= 1 "%" 1 取模运算
set /a var= 3 "<<" 2 左移位运算, 3的二进制为11,左移2位为1100,换成十进制就是12,自行验证
set /a var= 4 ">>" 2右移位运算,4的二进制为100,右移动2位为1,结果为1
思考题:
求2的n次方:
2.通过set进行字符串替换:
语法:set variable=%PATH:str1=str2%
上面的意思就是把字符串 PATH中的str1替换成str2
看个例子:
@echo off
set a= 我 是 传 奇
echo 替换前的值: "%a%"
set var=%a: =%
echo 替换后的值: "%var%"
pause
替换前的值:“ 我 是 传 奇 ”
替换后的值:“我是传奇”
变量中的所有空格都被替换掉了
另外,这个格式不仅可以用在set中,你也可以直接使用:
echo %a: =%
3.通过set进行字符串截取:
语法:set variable:%a:~[m[,n]]%
方括号表示可选,%为变量标识符,a为变量名,不可少,冒号用于分隔变量名和说明部分,符号~可以简单理解为“偏移”即可,m为偏移量(缺省为0),n为截取长度(缺省为全部)@echo off
set a=ABCDEFGHIJKLMN
set var=%a:~1,2%
echo "%var%"
pause
返回了“BC”就是从第一位开始,取后面2位,该命令还支持以下格式:
%a:~0,n% 相当于函数left(a,n) 取左边n位
%a:~-m% 相当于函数right(a,m) 取右边m位
%a:~m,n% 相当于函数mid(a,m+1,n) 从m+1位开始取n位
%a:~m,-n% 相当于函数mid(a,m+1,len(a)-m-n),从m+1位开始,至倒数n+1位
%a:~m % 相当于函数mid(a,m+1,len(a)-m) 或者right(a,len(a)-m),从m+1位开始取右边全部。
现在我们需要说明一些比较重要的东西,就是变量延迟,让我们先看一个例子:
@echo off
set a=4
set a=5 & echo %a%
pause
返回结果:
4
为什么不是5而是4呢?
我们之前曾经说过,批处理程序执行,是按行读取的,读取一行后,在实际处理前,需要做预处理。
那么这里,批处理首先把“set a=5&echo %a%”作为一行命令读取进来,注意不是分成2条,然后把a=4作为变量赋值给这行中的%a%变成“set a=5&echo 4”然后才执行,所以我们就看到显示了一个4
那么要怎么解决这个问题呢,我们就需要开启变量延迟,语句是:
setlocal enabledelayedexpansion
现在重写刚才的例子:
@echo off
setlocal enabledelayedexpansion
set a=4
set a=5 & echo !a!pause
返回结果:
5
现在,由于开启了变量延迟,批处理能够感知到变量的变化了,结果我们的到了预期。需要注意的是,开启变量延迟后,变量需要用“!!”一堆叹号括起来,而不再是“%%”一对百分号。
这个功能会在for循环中被经常用到,例如:
setlocal enabledelayedexpansion
for /l %%i in (1,1,5) do (
set a=%%i
echo !a!
)