在使用“set var = text”命令后,在cmd中使用“echo%var%”为什么没有字符串输出?

13

我使用 set 命令在 cmd 中设置了一个变量,然后尝试通过 echo 命令输出它。

以下是一个示例:

C:\Users\Logan>set var = text

C:\Users\Logan>set var
var = text

C:\Users\Logan>echo %var%
%var%

C:\Users\Logan>
有没有一种方法可以强制 cmd 输出变量的值而不是原始文本?
2个回答

26

将值/字符串分配给环境变量

最好使用启用命令扩展的以下语法来定义或修改环境变量:

set "var=text"

该命令是 set,参数为 "variable=value"

如果启用了命令扩展(默认情况下启用),则参数字符串可以像所有命令一样用双引号括起来。

如果在 variable=value 周围不使用双引号,则命令 set 会将第一个等号后直到行末的所有内容解释为字符串值,并将它们分配给变量,包括行末的不可见空格和水平制表符。

变量名以第一个非空格字符(如果使用了双引号,则以双引号后的第一个字符)开头,以等号左侧结尾。变量分配的值从等号右侧开始,一直到行末或最后一个双引号结束。

set VAR = TEXT

上面的命令行创建了一个名为VARSpace的环境变量,并将字符串SpaceTEXT分配给该变量。

用法:

set var="text"

通常这样做是不正确的,因为会将带引号和所有尾随空格和制表符的文本分配给变量var。在另一行代码中加上引号引用var通常会导致错误消息,因为变量本身已经包含了引号。有关更多详细信息,请参见如何设置带有空格的环境变量?中的答案。

例如:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "var=text"
set "var = text"
set "var1=and more text"
set var2="and more text"
set var3="text with 1 trailing space" 
set var
echo var3=%var3%^<- Do you see the trailing space?
echo/
set UnwantedSpaceVar=Hello 
echo %UnwantedSpaceVar%! ^<- Where does the space come from?
echo/
echo There is a trailing space after Hello in this code snippet.
echo/
set "TrailingSpacesIgnored=Hi"   
echo %TrailingSpacesIgnored%! ^<- The 3 trailing spaces above are ignored.
echo/
endlocal
pause

运行这个小批处理代码会产生以下输出:

var=text
var = text
var1=and more text
var2="and more text"
var3="text with 1 trailing space" 
var3="text with 1 trailing space" <- Do you see the trailing space?

Hello ! <- Where does the space come from?

There is a trailing space after Hello in this code snippet.

Hi! <- The 3 trailing spaces above are ignored.

即使文本本身包含1个或多个双引号,也可以将variable=value用引号括起来。

set "Quote=""

这行代码定义了变量Quote,其值为"。命令set将等号左边第一个引号到最后一个双引号之间的所有内容解释为要赋给变量名称(在第一个引号和第一个等号之间)的值。

注意:带有"并紧接着&&&||的字符串值,在使用set "variable=value"时可能会被误解释而导致意外行为,可以通过运行包含以下两行的批处理文件来观察到:

@echo off
set "Variable=Value with one double quote in the middle" & echo Oh, there is something wrong here!"

Value with one double quote in the middle" & echo Oh, there is something wrong here! is the string to assign to the environment variable, but assigned to the variable is just Value with one double quote in the middle and the rest of the line after " in the middle and after & interpreted as conditional operator and not literally is interpreted as additional command to execute by cmd.exe. The same problem exists with && or || after a " with 0 or more spaces/tabs between. This problem is not caused by command set. It is caused by Windows command processor which splits the line up into a command line with set and one more command line with echo with conditional execution of the echo command line.

禁用命令扩展以进行变量赋值

如果在批处理文件(或Windows注册表,这非常不常见,我从未在任何Windows计算机上看到过)中使用setlocal DisableExtensions 禁用了命令扩展,那么就不能使用命令语法set "variable=value"。执行批处理文件会导致语法错误。

只有在启用命令扩展的情况下,才能使用set variable=value,其中值可能包含双引号,并且对尾随空格/制表符也要进行特别注意,因为它们也分配给了环境变量。

在命令提示符窗口中运行cmd /?setlocal /?以获取有关命令扩展及受命令扩展影响的命令的更多信息。注意:受影响的命令输出列表不包括exit,如Where does GOTO :EOF return to?问题的答案所述。

通过算术表达式进行变量赋值

使用带有选项/A的命令set会完全更改第二个参数的解析,即在set /A之后的字符串。选项/A作为第一个参数时,第二个字符串被解释为算术表达式,因此与将字符串值分配给环境变量的方式处理完全不同。环境变量始终是字符串类型,永远不是整数类型。

使用选项/A需要启用命令扩展,否则命令set会完全忽略该行的其余部分,而没有任何错误消息。

通常不建议只使用算术表达式为环境变量赋值,例如使用set /A var=1。使用set "var=1"set var=1(没有尾随空格)会稍微快一些,因为环境变量始终是字符串类型。

在算术表达式中,空格被解释为变量名、数字和运算符的分隔符。因此,命令行set /A var = 1 不会定义一个名为VAR Space的变量,其字符串为Space1,而set var = 1会定义一个名为VAR的变量,其字符串值为1(批处理文件将1作为具有十六进制代码值31的字符),并将其从字符串转换为带有两个值0x31和0x00(字符串终止符)的整数,再转换回字符串。

通过提示符分配变量

此外,使用带有选项/P的命令set会更改变量名称和等号后面字符串的解析方式。变量名称和等号后面的字符串被解释为输出的提示文本,而不是要分配给环境变量的字符串。

环境变量将被分配为提示用户输入的字符串(或从文件或命令/应用程序重定向的字符串),或者在用户在按下RETURNENTER之前未输入任何内容的情况下,保留其当前值,如果在提示符之前没有定义,则仍未定义。

使用选项/P需要启用命令扩展,否则命令set会完全忽略行中的其余部分,而没有任何错误消息。

提示用户输入字符串的最常用语法如下:

set /P var="Please enter something: "
set 命令在这种情况下会自动移除提示文本周围的双引号并打印到 STDOUT (如果未重定向,则为控制台窗口)。但是以下方式也可以工作:
set /P "var=Please enter something: "

请阅读此答案,了解有关提示文本解析以及如何在周围添加双引号的详细信息。


1
  1. 对于语法set "VAR=Text",您应该提到只有在启用命令扩展的情况下才能正常工作(请参阅cmd /?setlocal /?)。
  2. 对于set /P,最佳语法实际上是set /P VAR="请输入内容:",因为如果提示文本本身以引号开头,则语法set /P "VAR="是被禁止的:"可能会导致意外结果,而set /P VAR=""是被禁止的:"不会。
- aschipfl

14

=前后删除空格:

set "var=text"
echo %var%
text

好的,它能工作,但为什么?你也可以使用 set /p 吗? - user3716786
5
当您执行set var = text时,实际上是在创建一个名为var的变量(注意r后面的空格)。 - aphoria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接