用户
搜索

【教程】Batch 入门教程 - 第二章:进阶!认识变量相关概念

2019-1-28 14:55| 发布者: 小i| 查看: 89| 评论: 0|原作者: subilan

进阶


进一步阶梯。不是吗?


进阶概述


我们在之前所接触到的三个指令仅仅是 Batch 中的冰山一角,一些比较重点的指令都会放在本章节中进行讲述,因此该章节的内容较另外的几个章节更加重要。在进阶章节中,您将会了解到变量逻辑判断调用与传参函数这几大概念。


在本次发布中,我们来了解第一大概念:变量。


变量


变量(Variable),在初中对函数的学习中我们可能接触到了这个名词,当然,如果您还没有接触到没有关系,您只需要将它理解为一种“一种可以改变的值”即可。在计算机中,变量的含义会更加清晰,因为它的确是可以变的。


我们如果提到变量,就必定会谈到赋值(Assignment)。这个赋值并不是代数中的赋值(名词),而是一个动宾短语。赋,即赋予,给予,这个词的意思很明显了,就是给予一个值。给予谁值呢?我们就要谈到变量名(Name)了。变量名一般是可以随便取的,但是如果我们想要更好地去分辨,我们最好取一些有意义的名字。


set


set 是变量操作最基本的指令,它能够指定一个变量名并给它赋值。下面是一个常见的变量赋值表达式:


set a=1

其中,set 为变量操作指令,它是不可缺少的。a 是变量名,它的值则是 = 后的 1。那么,= 是等号吗?不是。在计算机领域,= 从来没有等号的意思,它被称为赋值运算符(Assignment Operator),只要看到它,就代表着左侧与右侧相等,但是它并不表示相等关系。


也就是说,如果我们要表达“a 与 1 相等”,那么我们需要的是 a==1 而不是 a=1。假设此时 a 的值为 hello,那么我们若执行


set a=1

此时 a 的值会被彻底改变,变成 1。也就是说,a=x 任何时候都成立,因为它是用来改变左侧变量名所对应的值的,而 a==x 仅在 a 真正与 x 相等时成立。


经过一系列的纠结和解释,我们最终得到了一个名为 a 的变量,它的值为 1。那么这个时候我们就要想办法来使用它。能不能与之前的 echo 结合起来呢?


set a=1
echo %a%

得到 1。是可以的。在 Batch 中,您可以用 %变量名% 的形式来表示一个变量,并且在任何地方都可以用,比如


set a=set
set b=a
set c=^=
set d=1
set e=%a% %b%%c%%d%
%e%
echo %a%
pause
exit

这个突如其来的奇奇怪怪程序也许非常难懂。接下来我们慢慢分析。


首先我们可以看到,我们定义了 5 个变量,分别叫做 a, b, c, d, e。那么您能说出它们的值是多少吗?我相信答案是肯定的,除了 ce


a 的值为 setb 的值为 ac 的值为 =d 的值为 1。那么,如果我们一个一个地 echo 它们呢?


echo %a%
echo %b%
echo %c%
echo %d%
pause
exit

我们得到的结果将是这样的:


set
a
=
1

这看起来就像是一个指令:


set a=1

这样您也许可以猜到 e 的值是什么了。没错,e 的值就是 a, b, c, d 的组合。可以注意到,%a% 右边有一个空格,其它的都是相连的,这样组合起来也是不会变的。那么把


%a% %b%%c%%d%

组合起来,我们就得到了


set a=1

然后下面有一个单行,写着


%e%

这样,在 e 的值被赋为 set a=1 后,再把 %e% 当作指令执行,我们就相当于是执行了指令:


set a=1

随后再 echoa 的值,我们得到的是 1


结果


转义字符


为什么 %c% 的值是 = 而不是 ^=


首先我们观察:


set c=^=

在这里,如果我们去掉了中间的 ^,那么这就是一个错误的指令,因为 == 会被识别成判断是否相等的运算符,而右边又是空的,更何况 set 没有这种用法。


set c==

所以我们需要让 cmd 知道我们是想让 c 等于 =(等于等于)。于是 ^ 的用处有了。它叫做转义符(Escape Character),用来把原本有特殊含义的符号给转义成一般的字符。


转义符的作用很多,您能想到吗?


如果我们想要输出一句话,这句话里包含 %a%,但是我们并不想要输出 a 的值,而仅仅是输出两个百分号和一个 a,怎么办?转义符的用处有了。我们可以这样写:


echo %%a%%

这里我们又用到了一个转义符,它叫做“双百分号”,但它只能在使用变量转义的时候起作用。因而


set c=^=


set c=%%=%%

不相等。


^转义符的效用是它后面的 1 个字符,%% 转义符用来代表一个正常没有特殊含义的 %。使用 %%a%%,我们得到的结果就不是 a 的值了。我们看一个示例:


set a=1
echo %a%
echo %%a%%

这样,我们得到的结果是:


转义 Sample


set /p


set 指令有非常多的参数。在本教程中介绍 /p/a 两种。首先,set /p 属于暂留性指令中的一种,也是用户输入的第二种途径。如果您想要让用户自己来定义变量的值,您将需要用到 /p


set /p a=

/p 参数的 set 指令,赋值运算符右侧无论是什么,都不会影响到它的值。若我们单单执行 set /p a=,我们将得到


一个输入空框


这是一个输入空框,我们可以随意在这里输入东西。例如,我们输入 123456,那么什么也不会发生:


输入 123456


但是如果此时我们调出 %a% 的值,效果就出现了:


调用 a 值


也就是说,我们输入的任何东西都已经被赋入了变量 a 里。/p 参数的用处就在如此。


但是,每一次都是这个输入空框,用户根本不知道输入什么。这样,我们就可以再赋值运算符右侧加上提示文字,来提示用户这是在输入什么。运行如下程序


home.php?mod=space&uid=46675 off
set /p password=Please enter your password:
echo Your password is %password%
pause
exit

效果如图


Sample02


其中,thisismypasswd 是笔者手动输入的部分。


那么,我们结合先前将变量直接当作指令执行的方式,来制造一个假的 cmd 控制台:


@echo off
echo Microsoft Windows Command Prompt [zxsq-anti-bbcode-Version 10.0 - 1809]
echo Copyright (C) Microsoft Corporation All rights reserved。
set /p command=
%command%
pause
exit

这时,我们输入的值会直接被赋入 %command% 内,紧接下一行就是直接把变量的值当作指令来处理。也就是说,我们输入一条指令,就会被直接当作指令来处理,从而实现假控制台的效果。


利用这条思路,我们就可以自定义我们自己的控制台了。当然这是后续的内容。


set /p <


多了一个 &lt;,意义就完全不一样了。准确来说,这种用法是建立在文件重定向运算符 &lt; 上的。它的具体用法:


set /p a=&lt;1.txt

左侧没有多大的区别,仍然是变量名,但是右侧则是一个 &lt; 加上一个文件。严格来讲,这个文件只能是纯文本文件(扩展名随意,只要不是二进制即可)。这条指令的意思是从 1.txt 读取第一行的所有内容并赋值到 %a% 中。


我们不妨直接做个实验:


:: MyFirstProgram.cmd
set /p a=&lt;1.txt
echo %a%

:: 1.txt
Hello World!

Sample03


这样,从文件读取内容也成功了。但是如果有多行文本呢?出于局限性,这个方法只能读取第一行的内容。在后面的学习中,我们会介绍如何读取全部内容,以及如何选择性地读取指定行的内容。


set /a


指定 /a 参数可以进行数学运算操作。如果 set 指令拥有 /a 参数,那么它的赋值运算符后面的变量不需要带上百分号。


例如:


set a=1
:: 如果这个时候我想让 b == a == 1,那么
set b=%a%

这是我们常用的方法。但是如果加上了参数 /a,我们可以直接这样写,效果是一样的:


set a=1
set /a b=a

但是前提是赋值运算符后的变量必须为数字。因为 /a 是专为数学运算而设计的,所以这样能够让计算写作时更加快速。


一个简单的加减乘除程序就可以通过参数 /a 来实现:


set a=1
set b=1
set /a c=a+b
set /a d=a-b
set /a e=a*b
set /a d=a/b
echo a=%a%, b=%b%
echo a+b=%c%
echo a-b=%d%
echo a*b=%e%
echo a/b=%d%
pause
exit

我们的效果是这样的:


Sample04


这代表着在 /a 参数的前提下,赋值运算符后将可以直接写四则运算符号。但是这远远不够。因为批处理的局限性,目前是无法计算超过 32 位的数字以及任何浮点数的(所以不建议用批处理计算除法)。不过,这样就相当于是实现了计算器的核心功能。


至此,set 介绍得就差不多了。接下来我们了解一下环境变量


环境变量


环境变量(Environment Variable),是指系统已经预先配置好的父进程环境默认设置。简要来讲,就是一些包含您计算机的基本信息的变量,虽然说叫做”变量“,但是实际上如果您的系统没有从底层上发生改变,这些变量的值是不会改变的。


环境变量在批处理的作用非常巨大,可以节省我们编写代码的时间,也能让我们的代码更加适配其它人的电脑。我们举个例子。


众所周知,很多人的 Windows 系统是安装在盘符为 C: 的存储空间的,因此如果我们在批处理内要对系统盘内的项进行操作,我们必定需要写路径。例如,我们要用上文中提到的 set /p 指令来读取位于系统盘根目录的 1.txt,那么怎么做?(忽略权限)


set /p content=&lt;C:\1.txt

一般我们的思路当然就会是这样的了,但是,您有没有思考过,万一真的有人系统盘不在 C 盘呢?(实际上这种情况非常非常普遍)这条指令岂不是失去意义了?这个时候,环境变量就发挥作用了。环境变量可以根据不同的电脑而改变,这就是它”变“的地方。


例如,在 Windows 中有一个环境变量,叫作 %SYSTEMDRIVE%(环境变量不区分大小写),它的字面意思是系统盘符(System Drive Volume),这也是它所代表的。那么我们可以直接在 echo 指令中输出它,因为它在系统安装的时候就被定义了。


SYSTEMDRIVE


我们得到的是 C:,这正是我们系统盘的盘符。


而如果某人的电脑系统盘是 E:,那么这个变量的值就会等于 E:。利用这个原理,我们就可以适配所有的电脑了,于是把我们的指令修改成


set /p content=&lt;%SYSTEMDRIVE%\1.txt

这样,这条指令就有了万能性。


环境变量的使用方法基本上就是这样,接下来我们列出一些常用的环境变量:

































































































环境变量名称 用途 / 含义 示例 备注
%USERNAME% 用户的名称 Administrator 这是用户的名称,可以更改,但是不能通过直接修改变量值更改。
%COMPUTERNAME% 电脑的名称 Your Computer 与用户名原理相似,可以更改。
%PROCESSOR_ARCHITECTURE% 处理器架构 AMD64 一般不换 CPU 是不会改变的。
%PROCESSOR_IDENTIFIER% 处理器型号 Intel64 Family 6 Model 94 Stepping 3, GenuineIntel 笔者没有看懂这个型号,很显然它不是我们想要的
%OS% 系统内核名称 Windows_NT 一般就是 Windows_NT,除非您没有用 Windows。
%ComSpec% 命令处理程序的完整路径 与 %Systemdrive%\Windows\System32\cmd.exe 相等 一般不可能是 Powershell。
%DATE% 当前的日期 2019/1/25 日期格式按照日期格式的设置而定,因此可以被改变。
%ERRORLEVEL% 错误代码 0, 1, 9009, -1 这个环境变量比较复杂,后面将会详细讲述。
%ProgramFiles% Program Files 文件夹的位置 与 %SystemDrive%\Program Files 相等 64 位系统时,该变量仍然会显示 Program Files 而不是 Program Files(x86)。
%SYSTEMDRIVE% 系统盘盘符 C: 系统装在哪个盘,它就等于什么。并且它永远没有 \ 而是以 : 结尾。
%SYSTEMROOT% Windows 所在位置,准确来说,是系统启动的位置 大部分时间与 %windir% 即 %SystemDrive%\Windows 相等 系统启动的位置,正常情况下是 Windows 文件夹所在位置。
%windir% Windows 所在位置 与 %SystemDrive%\Windows 相等 这就是 Windows 文件夹所在的位置。
%USERPROFILE% 用户文件所在位置 与 %SystemDrive%\Users\%Username% 相等 这是当前用户的用户文件夹所在位置,例如桌面则是 %USERPROFILE%\Desktop
%RANDOM% 随机数字(0~32767) 1 这是一个好玩的环境变量,当然。如果您连续 3 次以 0~32767 的范围 echo 出了相同的数字请截图联系笔者获取神秘大奖一份。后文中会介绍如何缩小随机数字的范围。

变量截取与替换


如果我们希望将一个变量分段,只取其中一部分内容,在 Batch 中是有方法的。


set a=1234567890
echo %a:~0,1%

上面的执行结果是 1。看吧,这是一个您不认识的变量写法。:~0,1 就是变量控制符。一般地,在 Batch 中,我们对变量截取有以下原则:


%操作变量名:~始, 终%

其中,操作变量名很好理解,这是我们要采取截取工作的变量。例如,我们要截取变量 a,那么操作变量名就是 a(from Index),指定从哪一(Index)开始截取,(to Index)指定截取到的位。


在计算机中,位是从 0 开始的。也就是说,我们日常生活中所表示的 1,在这里就是 0。观察以下数据:


1234567890

请问这组数据中的第一个数字是什么?是 1。但是,如果我们要在计算机内表示的话,我们要说它在第 0 位。以此类推,如果我们要截取变量的前 8 位,那么我们应当写成


%a:~0,8%

这行代码代表截取变量 a 的第一位至第八位。如果我们仿照上例执行


set a=1234567890
echo %a:~0,8%

我们将得到 12345678。这种截取也适用于非 0 开头。需要注意的是,开头的位必须与我们现实生活中所数的位数少 1。例如:


set a=你好啊
echo %a:~1,1%

输出的结果是 。这行代码代表从第 2 位开始,截取 1 个字符。那么我们就直接截取了第 2 位本身。如果我们将终改为 2,我们得到的结果是 好啊,即从第 2 位开始,截取了 2 位。


请您参考如下例子来好好了解一下变量截取:


set a=3.141592653589794626
echo %a:~0,2%
:: 得到:3.1
echo %a:~11,1%
:: 得到:5
echo %a:~1,1%
:: 得到:.

我们同样可以反过来,从相反方向截取。例如,


set a=3.14
echo %a:~-1%

这种用法里没有始和终的区分。以上例子代表截取 a 的倒数第一位,我们得到的结果是 4。如果我们使用 echo %a:~-2%,那么我们截取的是倒数的两位,结果是 14。以此类推,当我们使用 echo %a:~-n% 的时候,实际上是截取了这个数据的倒数 n 位(即从倒数第 1 位一直截取到倒数第 n 位)。


此外我们还可以结合起来用:


set a=3.14
echo %a:~0,-1%

我们得到的结果是 3.1。这行指令代表截取从正数第一位一直到倒数第一位之前的那一位的数据。以此类推,当我们使用 echo %a:~b,-c% 的时候,实际上是截取了这个变量从正数第 a+1 位到倒数第 |c|+1 位的数据。


至于变量替换,相对于变量截取,比较简单。


set a=我好!
echo %a:我=你%

我们得到的结果是 你好!。也就是说,%a:A=B 即将变量内任何A 完全匹配的内容全部替换成 B




小i,如果您要查看本帖隐藏内容请回复
鲜花
鲜花
握手
握手
雷人
雷人
路过
路过
鸡蛋
鸡蛋