通过前面对批处理的介绍,我们已经准备好了开始编码,今天我们将讨论变量、值和批处理的set命令,该命令将一个值赋值给一个变量。如果您用过其他计算机语言做过开发,这些可能显得微不足道,但是批处理有一些独特的特性需要我们去注意。
通过本文,您将学习如何在控制台中显示变量的值,以确认它已被正确设置。此外,我将介绍命令分隔符,它允许您在一行中输入多个命令。我还将向您展示如何创建注释和设置保存在计算机上的变量,这些变量即使在bat文件关闭后也仍然可用。最后,您将学习如何在命令提示符下访问任何批处理命令的文档,这对于使用bat文件的任何人来说都是一项有用的技能。
设置和解析变量
变量是一个命名字段,它在内存中定义了一个位置,该位置保存了供以后使用的值。大多数计算机语言允许并且通常要求在赋值之前将变量定义为特定的数据类型,常用的是字符串或数字。批处理通常不用设置具体的数据类型;变量在第一次被“设置”为一个值时就存在了,这个值可以包含字母、数字和其他字符。然后由编码人员决定是否将它们视为特定的数据类型。本文的重点是为变量赋值这一看似简单的任务。
考虑一个变量的例子,一个程序员可能有一个包含他们情绪状态的字段。变量被定义为或命名为myMood
,其中两个可能的值是happy
和sad
。要将变量设置为happy,这里可以使用set命令:
shell
代码解读
复制代码
> set myMood=happy
执行完这个命令后,myMood
变量包含了happy
值。
下面的命令将删除先前的值并用另一个值替换它:
shell
代码解读
复制代码
> set myMood=nonplussed
但是如何确定这个或其他变量的值呢?在批处理中,显示变量值的行为被称为解析变量,通常在变量两边加上百分号来完成。也就是说,在前面的set命令执行后,%myMood%
将解析为nonplsed
。现在,为了实际看到解析变量的结果,我们需要了解变量之外的知识。
显示变量的值
在这里我们将学习如何在计算机屏幕上快速显示变量的解析值,但这种技术的用途远不止于此。我们将在以后的文章中来演示批处理的许多其他特性,例如使用它作为测试技术,这对任何批处理程序都是有用的。
写入控制台
要在屏幕上显示变量的内容,我们需要两个额外的命令:echo和pause。下面我们创建一个简单的bat文件。在计算机上打开一个新文件夹,比如D:\Batch\
,并在其中创建一个名为Mood.bat
的bat文件,代码如下:
bash
代码解读
复制代码
set myMood=happy echo My mood is %myMood%. pause
这里bat文件Mood.bat
显示一个已解析的变量。
如果双击或打开Mood.bat
, bat文件将被执行,并出现一个带有白色文本的黑色窗口。这个窗口就是DOS窗口或者叫控制台。
前面我们已经了解了set命令。在这里,echo命令是将语句的其余部分(不包括echo本身及后面的空格)写到控制台。显示文本My mood is和尾随空格,后跟myMood的内容或值(即文本happy)和最后的句号。pause命令使控制台保持打开状态。没有它,窗口将会一闪而过,我们什么效果都看不到(即窗口打开后立即关闭了)。
打开后控制台具体显示内容如下:
bash
代码解读
复制代码
D:\Batch>set myMood=happy D:\Batch>echo My mood is happy. My mood is happy. D:\Batch>pause 请按任意键继续. . .
每个命令前面都有当前目录D:\Batch\
,后面跟着一个大于号(>)作为分隔符。
第一行显示set命令的执行,第二行显示echo命令的执行。第三行是执行该echo的结果,即控制台输出。您可以看出它不是命令,因为前面没有文本D:\Batch>
。这里需要注意的是%myMood%
解析为文本happy
了。pause命令也会产生输出,为文本请按任意键继续…
,如控制台所示,执行将暂停,直到按下任何键,此时bat文件将结束,控制台将关闭。另外,请注意set命令不产生任何输出,因为它只是设置一个变量的值。
清除控制台
写入控制台的内容的一个问题是,命令与echo和pause命令的期望输出交织在一起。这里我们来看看一个快速清理的方法。在Mood.bat bat
文件的顶部添加@echo off
后再次执行:
bash
代码解读
复制代码
@echo off set myMood=happy echo My mood is %myMood%. pause
这个echo off
命令抑制的不是后续命令的实际输出,而是显示正在执行的每个命令的行—即以当前目录为前缀的行。此外,在echo命令前加上@符号(@)会阻止它自己的执行被写入控制台。
与前面相比,当执行修改后的bat文件时,控制台显示更加清晰:
整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
bash
代码解读
复制代码
My mood is happy. 请按任意键继续. . .
现在我们可以很容易地演示如何将myMood
变量初始化为gloomy
,然后将其重置为cheerful
:
bash
代码解读
复制代码
@echo off set myMood=gloomy echo My mood is %myMood%. set myMood=cheerful echo Now my mood is %myMood%. pause
结果显示同一个变量在两个不同的时间被解析为两个不同的值:
bash
代码解读
复制代码
My mood is gloomy. Now my mood is cheerful. 请按任意键继续. . .
随着我们的bat文件变得越来越复杂,echo命令可以将输出发送到控制台以外的地方。
set命令的特性
对于大多数编程语言来说,设置变量通常是一个简单的事情,但批处理与大多数编程语言不同。所有批处理程序员都需要了解set命令的以下特性,以避免将来某种程度的痛苦。
大小写敏感
仔细检查以下两个命令。它们看起来有点不同,但功能相同:
bash
代码解读
复制代码
SET myMood=whimsical set MYMOOD=whimsical
批处理命令和变量不区分大小写。在这里,set命令在一个命令中是大写的,在另一个命令中是小写的,但是解释器将它们视为相同的。您也可以在不改变功能的情况下使用Set。为了更好地衡量,sET和sET也以相同的方式工作。同样,您可以互换使用myMood、MYMOOD和mymood变量。但是,该值是按照键入的方式存储的,因此它是区分大小写的。如果变量被设置为WHIMSICAL,将被解析为WHIMSICAL;同样,如果它被设置为Whimsical,它将被解析为Whimsical。
这完全是风格和个人喜好的问题。我发现许多bat文件有太多的内容大写。大写是为了突出某些东西,但当所有东西都闪烁着霓虹灯时,什么都不突出。大多数批处理程序员将命令名称中的所有字母大写,但在我们这里,我只使用小写字符来表示所有批处理命令。另外,我也非常喜欢驼峰式变量。
注意:
驼峰大小写文本很容易阅读,即使它包含多个单词,没有空格或其他字符分隔。驼峰大小写文本的第一个字母可以是大写或小写。但是要符合驼峰大小写,所有后续单词的第一个字母必须大写,其余单词必须小写。MyMood就是一个例子(也称为Pascal或上驼峰)。相应的myMood也是一个很好的例子(也称为单峰或下骆驼)。
有效的变量字符
大多数编程语言对于变量名中允许的字符列表都有严格的规则。通常情况下,数字和26个字母(大写和小写)是允许的,只有几个特殊字符可以使用。但是批处理的独特之处在于,键盘上的几乎每个字符都是有效的变量名字符,但是我们应该尽量避免在变量名中使用数字作为第一个字符。
一些字符是非法的,因为它们在批处理中有特定的用途;例如,波浪号(~)、&号(&)、百分号(%)和小于号(<)和大于号(>)都是保留字符,但是其他几个字符会让不熟悉批处理的程序员感到惊讶。下面三个变量在批处理中也是合法的:
bash
代码解读
复制代码
set ;=semicolon set @=at set #=hashtag echo %;% %@% %#% pause
甚至下面的怪异变量也存储了文本,这实际上是在带有美元符号、点和不匹配括号的变量中工作的:
bash
代码解读
复制代码
set var$with.odd[chars}=This actually works
这个变量名演示了各种怪异的变量都是可能的,但是很难阅读,不推荐使用。
然而,在变量名中明智地使用这些字符可能是一个方便的工具。例如,一组相关变量可能都有一个开头或结尾下划线作为这种关联;number可以缩写为#,比NBR更简洁,比no更清晰。在后面,我将使用这个有趣的特性来构建数组和哈希表,这些数组和哈希表的名称包含括号。
赋值操作符周围的空格
以下是大多数熟悉其他语言的批处理程序新手都会犯的典型错误。仔细检查下面的set命令。
bash
代码解读
复制代码
set X = Hello echo The value of X is "%X%".
如果您期望echo命令的结果为
bash
代码解读
复制代码
The value of X is "Hello".
这是一个可以理解的错误,但毕竟是一个错误。结果是这样的:
bash
代码解读
复制代码
The value of X is "".
空引号表示X没有设置或设置为null,即什么都没有,甚至没有空格。
注意:
在上一篇文章中,我们提到在命令提示符中,与bat文件相比,语法和输出可能有所不同,这就是一个很好的例子。在命令提示符下输入的相同代码显示结果将不同:
bash
代码解读
复制代码
The value of X is "%X%".
在后面代码的执行过程中若存在什么异常,我们可以尝试着将代码放入到bat文件中执行试试。
现在上面代码中的set命令并不是那么复杂,它显然想将X设置为文本Hello?此外,它看起来很像其他现代的编程语言中的赋值命令,可以按需要执行赋值。
这是我们第一次出现问题,这个问题的关键是等号前面的空格。变量名以set命令后的第一个非空格字符开始,以赋值操作符或等号之前的字符结束——无论该字符是什么。因此,这里设置的变量长度为两个字符,X后跟空格:
bash
代码解读
复制代码
set X = Hello echo The value of X-space is "%X %"
解析带有尾随空格的变量现在会显示它的值,其中包含一个前导空格:
bash
代码解读
复制代码
The value of X-space is " Hello".
更容易犯的错误是在值后面的行末尾无意中添加一两个空格。因为仅仅在编辑器中查看文本并不明显,所以很容易忽略它。(在 Notepad++中, 视图--->显示符号--->显示空格与制表符)它将在每行的行尾将空格以点表示,将Tab键以箭头显示。
命令分隔符
&
是一种特殊字符,用作命令分隔符;它不像简单的文本那样被处理。例如,您可以将多行代码串成一行,每个命令用&
字符分隔:
bash
代码解读
复制代码
set ;=semicolon& set @=at& set #=hashtag
这在功能上等同于三个不同行的三个命令。
有时,这种技术对于合并简单和类似的命令很有用,但是过度使用它会使代码难以阅读。但是,我发现了命令分隔符的两种非常方便的用法。
向命令追加注释
命令分隔符的一种用途是在行尾添加文本,以便将其视为注释。rem命令根据它后面的文本创建注释。通常,我们将rem命令作为注释放在一些代码前面的行上,但我们也可以使用命令分隔符将其附加到特定命令上。例如,下面两行执行相同的逻辑:
bash
代码解读
复制代码
set myMood=reflective set myMood=reflective& rem This is a thoughtful and contemplative mood.
然而,第二行为阅读代码的人提供了更多的信息。
终止命令
命令分隔符的第二个用途是明确地终止命令,以便程序员可以清楚地描述是否存在任何尾随空格。下面的命令是否将变量设置为null、一个空格或多个空格?
bash
代码解读
复制代码
set myMood=
正如所写的那样,这是不可能的(除非您让编辑器将空格显示为可见字符)。
如果您没有阅读前面的内容,下面的命令可能会将变量设置为&符号:
bash
代码解读
复制代码
set myMood=&
但是这个命令明确地告诉读者,变量被设置为null,因为语句被紧接在相等操作符之后的&号终止。
同样地,当程序员可能希望变量具有一定的长度时,也存在这样的实例。下面的命令将变量设置为一个10字节的左对齐值,其中包含文本和三个空格:
bash
代码解读
复制代码
set myMood=pensive &
如果没有&符号,就很难确定文本后面有多少空格(如果有的话)。从技术上讲,&号并没有分隔两个命令,但它确实终止了一个命令。
显示变量信息
set命令还有一个更有趣的用法。当不使用等号时,它会写出变量的值,所以如果myMood变量已经定义了,你可以在bat文件中输入这个命令:
bash
代码解读
复制代码
set myMood
写入控制台的结果输出可能如下所示:
bash
代码解读
复制代码
myMood=hopeful
如果在set命令后只输入变量名的一部分,则将显示以该文本开头的所有变量。因此,下面的命令可能会输出多于myMood变量的值:
bash
代码解读
复制代码
set myM
也许,只是也许,它可能输出如下:
bash
代码解读
复制代码
Mymar=A Genus of Fairyflies myMood=hopeful
这样的变量不太可能被设置,但是如果它确实存在,并且如果这是机器上以mym开头的仅有的两个变量,那么输出应该是这样的。注意,该命令查找所有变量,而不考虑大小写。还要注意包含嵌入空格的变量值的示例。
在了解了该技术对完整变量名和部分变量名的处理后,我们可以将其扩展到完全没有变量名:
bash
代码解读
复制代码
set
这个不带参数的命令生成所有可用变量的列表,这些变量是在bat文件启动时加载的,以及来自bat文件本身的对列表的任何添加和修改。
设置变量持久化
set命令本质上是临时的。它在特定批处理流中定义变量,直到变量被重新赋值或脚本终止,此时通过set命令设置的所有变量都消失。但是有时我们希望变量可以被计算机上的其他进程或其他bat文件访问,并且在原始bat文件终止后很长一段时间内,甚至在计算机关闭并重新启动之后。我们想要的是一个极限集合命令,我们使用setx命令就是为了这个目的。
假设set和setx命令的语法是相同的,这是合乎逻辑的。除了一个变量、一个等号和一个值,但令人费解的是事实并非如此。setx命令不调用等号。相反,变量名和值由一个或多个空格分隔,如下所示:
bash
代码解读
复制代码
setx myMood puzzled
在讨论set命令时,很明显变量名和值确实可以包含空格。当在设置变量的命令中使用空格作为分隔符时,显然会出现一种问题。但是将变量名和/或值用双引号括起来可以快速解决问题。下面的命令创建了一个有两个单词名称的变量,并给它赋了一个两个单词的值:
bash
代码解读
复制代码
setx "my mood" "cautiously optimistic"
为了测试这一点,首先在一个bat文件中执行前面的语句,然后在另一个bat文件中甚至在命令提示符中执行以下命令:
bash
代码解读
复制代码
set my m
要查看效果,必须在setx命令完成后启动第二个bat文件或打开命令提示符,因为解释器在会话开始时使用计算机现有的变量加载会话。
将显示所有以my m开头的变量(不区分大小写,包括嵌入的空格),包括变量my mood
。除非这个变量被其他进程重新赋值,比如将来的setx命令,否则只要计算机是可操作的,它就会以这个值存在。
setx命令是一个很好的工具,可以帮助开发编译后的代码。当开发的特定程序最终在生产环境中运行时,它显然会在具有自己环境变量的不同机器上运行。当运行程序时,一些ide有一个很好的机制来模拟这些环境变量和文件连接器的设置;令人遗憾的是,其他人没有这些环境。一个很好的解决方案是启动之前在开发机器上设置所有需要的值。
对于用特定语言开发的每个程序,我将创建一个包含一系列setx命令的bat文件,每个命令对应需要持久设置的变量。在执行了bat文件之后,我可以让程序运行起来,它将找到我期望它在稍后的生产环境中执行时找到的所有环境变量。如果我想运行一个不同的程序,我可以先运行与它相关的bat文件,这既快速又容易,如果我觉得需要在完成后将一些变量恢复到之前的状态,我也可以为此创建一个bat文件。
命令行帮助
我们介绍的最后一个批处理命令是记录我已经讨论过的命令以及所有其他命令的命令。help命令接受另一个命令作为其参数,并返回关于该命令的大量信息,首先是对其函数及其一般语法的简要描述。
我将用set命令来演示,因为它是本文的核心。要调用帮助命令,请在命令提示符中输入它(在Windows开始菜单中输入CMD并按enter)。然后,要接收关于set命令的更多详细信息,请输入以下命令:
bash
代码解读
复制代码
help set
解释器产生了太多关于set命令的信息,下面显示部分信息:
bash
代码解读
复制代码
显示、设置或删除 cmd.exe 环境变量。 SET [variable=[string]] variable 指定环境变量名。 string 指定要指派给变量的一系列字符串。 要显示当前环境变量,键入不带参数的 SET。 如果命令扩展被启用,SET 会如下改变: 可仅用一个变量激活 SET 命令,等号或值不显示所有前缀匹配 SET 命令已使用的名称的所有变量的值。例如: SET P 会显示所有以字母 P 打头的变量 如果在当前环境中找不到该变量名称,SET 命令将把 ERRORLEVEL 设置成 1。 SET 命令不允许变量名含有等号。 在 SET 命令中添加了两个新命令行开关: SET /A expression SET /P variable=[promptString]
该命令的简要描述之后紧接着是它的通用语法,它显然是从命令名称本身开始的。方括号内的所有文本都是可选的。文本周围的方括号[variable=[string]]表明该命令可以在有或没有文本的情况下工作。请记住,不带参数的set命令返回所有可用变量的列表。嵌套的方括号更进一步,表明string也是可选的——也就是说,变量可以被设置为什么都没有。
某些命令的帮助提供了命令的使用示例,以及附加说明和可用选项列表。选项是分配给命令的设置或调整,用于打开或关闭一些附加功能。它们也被称为开关;事实上,help命令交替使用这两个术语。为了保持一致性,我将只使用更流行的术语选项,但是如果有人提到批处理命令开关,他们指的是一个选项。
选项通常是用正斜杠加一个字母来定义的,但你最终会遇到一些更复杂的选项。在命令提示符中向下滚动,显示set命令的帮助,以查看两个有趣且有用的选项。/A选项允许命令执行算术运算。/P或prompt选项用于设置用户输入数据的变量。
在前面的文章中,可能是你的第一个bat文件包含一个命令来复制一些文件。这里我们不会详细介绍xcopy命令,但在前面中,它使用了三个选项(/F、/S和/Y)。它们到底能做什么还不重要。重要的是,它们可以打开或关闭某些功能,并使用帮助命令对它们进行记录。
有些命令有很多选项,有些只有几个选项,还有一些没有选项。在介绍命令时,我将详细介绍我认为重要和有用的选项,但您可能希望使用help命令来查找更完整的列表。但是,在help命令中找不到一些未记录的选项,要发现这些gem,请访问 ss64.com/nt/ 或其他资源。
我建议在第一次使用特定命令时使用帮助,或者作为可用选项的提醒。尝试将它用于本文中提到的任何其他命令,甚至帮助命令本身。在命令提示符下输入这个:
bash
代码解读
复制代码
help help
显示help命令的文档。
重要:
跟随任何批处理命令使用/?检索相同的信息。即输入set /?工作方式与帮助集相同。以下两个命令都表示查看某个命令的帮助信息:
bash
代码解读
复制代码
help set set /?
总结
批处理编码可能很复杂,甚至像设置变量这样看似简单的事情也可能有一些细微差别。在本文中,我们详细介绍了set命令及其怪异之处,并将其与setx命令进行了比较,后者可以持久地设置变量。您还学习了如何解析变量并在控制台上显示它们。现在,您可以在bat文件中添加注释,将命令分隔符用于多种用途,最重要的是,可以快速访问任何命令的文档。
下一步,我们将进一步讨论变量,特别是变量的作用域。我们将讨论如何定义变量在何时何地拥有某些值,以及如何启用延迟展开的强大功能。