为啥在cmd中使用'set var = text'命令后没有'echo %var%'的字符串输出? [复制]

Posted

技术标签:

【中文标题】为啥在cmd中使用\'set var = text\'命令后没有\'echo %var%\'的字符串输出? [复制]【英文标题】:Why is no string output with 'echo %var%' after using 'set var = text' command in cmd? [duplicate]为什么在cmd中使用'set var = text'命令后没有'echo %var%'的字符串输出? [复制] 【发布时间】:2022-01-14 03:24:23 【问题描述】:

我用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 使用 echo 变量而不是原始文本?

【问题讨论】:

【参考方案1】:

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

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

set "var=text"

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

参数字符串可以像所有命令一样用双引号括起来,只要命令扩展默认启用。

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

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

set VAR = TEXT

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

用法

set var="text"

通常是不正确的,因为这会导致将包含引号的文本以及所有尾随空格和制表符分配给变量var。现在在另一个带有引号的代码行上引用 var 通常会导致错误消息,因为变量本身已经带有引号的文本。更多详情请查看How to set environment variables with spaces?上的答案

例子:

@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 将第一个等号后到最后一个双引号的所有内容解释为要分配给名称在第一个引号和第一个等号之间的变量的值。

注意:带有" 和下一个&amp;&amp;&amp;|| 的字符串值甚至可能在使用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" &amp; echo Oh, there is something wrong here! 是分配给环境变量的字符串,但分配给变量的只是Value with one double quote in the middle 和中间" 之后和&amp; 之后的其余行解释为条件运算符而不是字面上解释为由cmd.exe 执行的附加命令。 &amp;&amp;||" 之间存在 0 个或多个空格/制表符之后存在相同的问题。此问题不是由命令 set 引起的。它是由 Windows 命令处理器引起的,它将一行拆分为一个带有 set 的命令行和一个带有 echo 的命令行以及 echoconditional execution /strong> 命令行。

禁用命令扩展的变量赋值

如果命令扩展名在批处理文件中被setlocal DisableExtensions 禁用(或在Windows 注册表中,这是非常罕见的,我在任何Windows 计算机上从未见过),则不能使用命令语法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=1set "var=1" 或只是 set var=1(并且没有尾随空格)会快一点,因为环境变量始终是字符串类型。

在算术表达式中,空格被解释为变量名、数字和运算符的分隔符。出于这个原因,命令行set /A var = 1 没有定义一个名称为 VARSpace 的变量和字符串 Space 1 就像set var = 1 一样。 set /A var = 1 在将 1 从字符串(批处理文件包含 1 作为十六进制代码值为 31 的字符)转换为字符串值 1 后定义了一个名为 VAR 的变量具有值 1 的整数并返回具有两个值 0x31 和 0x00 的字符串(字符串以 null 结尾)。

通过提示分配变量

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

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

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

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

set /P var="Please enter something: "

在这种情况下,命令 set 会在打印之前自动删除提示文本周围的双引号以处理 STDOUT(如果未重定向,则为控制台窗口)。

但工作也是:

set /P "var=Please enter something: "

请阅读this answer了解更多关于提示文本解析以及如何输出带有双引号的提示文本。

【讨论】:

1.对于语法set "VAR=Text",您应该提到这仅在启用命令扩展的情况下有效(另请参见cmd /?setlocal /?)。 2.对于set /P,最好的语法其实是set /P VAR="Please enter something: ",因为如果提示文字本身以引号开头,set /P "VAR=" is prohibited: "语法可能会导致意想不到的结果,而set /P VAR="" is prohibited: "不会。【参考方案2】:

你需要让你的文本离等号更近:

set var=text
echo %var%
text

【讨论】:

好的,它有效,但为什么呢?你也可以用set /p这个吗? @Logern 当您执行set var = text 时,您实际上是在创建一个名为var 的变量(注意r 后面的空格)。

以上是关于为啥在cmd中使用'set var = text'命令后没有'echo %var%'的字符串输出? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为什么没有字符串输出与“回声%VAR%”在cmd中使用“设置VAR =文本”命令后? [重复]

java jdk安装成功了,但是为啥我在cmd命令模式中javac 类名.java中总是找不到文

bat SET中替换字符串(用变量代表需替换的字符串)

为啥在“set /p”提示时使用 Ctrl+C 取消 Windows 批处理脚本会产生不一致的行为?

为啥我在CMD里输入lsnrctl,提示不是内部或外部命令????

为啥我的电脑CMD 中mysqldump和mysql命令不能用