为什么 Windows 批处理脚本输出变量为“ECHO 已关闭。”而不是实际值

为什么 Windows 批处理脚本输出变量为“ECHO 已关闭。”而不是实际值

我编写了一个 Windows 批处理脚本来创建一个数组并尝试打印该数组的每个元素。

然而,输出是ECHO is off.而不是实际值,例如"Apple"

当我改变的时候ECHO is off.@echo on,结果刚刚变为ECHO is on

@echo off
    
Rem Create variable
set fruit[0]="apple"
set fruit[1]="orange"
set fruit[2]="pear"
set fruit[3]="lemon"
    
REM x is the last index of the array
set x=3
    
REM for loop [with 0 for start, 1 for step, x for end]
FOR /L %%a in (0,1,%x%) DO (
   call set var=%%fruit[%%a]%%
   set var
   echo %var%
   call echo "Text2" 
  )
 
pause

命令call set var=%%fruit[%%a]%%是正确的,因为当命令set var运行时,输出可以成功显示类似var="lemon",这意味着%var%已成功存储 的值"lemon"
但是,以下命令echo %var%输出是ECHO is off.

这是怎么发生的?

以下是从cmd捕获的批处理脚本结果。(@echo off

var="apple"
ECHO is off.
"Text2"
var="orange"
ECHO is off.
"Text2"
var="pear"
ECHO is off.
"Text2"
var="lemon"
ECHO is off.
"Text2"
Press any key to continue . . .

答案1

> echo /?
Displays messages, or turns command-echoing on or off. 
 
ECHO [ON | OFF] 
ECHO [message] 
 
Type ECHO without parameters to display the current echo setting.  


echo命令可以在屏幕上显示消息、变量和/或消息和变量,但它也可以将当前状态返回给命令echo,因为这是发送(或回显)动作的行为的定义。

对于脚本/提示符中的一个或多个命令,当设置为省略它们时将不会出现这些命令(echo off)。

由于您的变量没有值(在运行时),您的%variable% == ""(没有,没有字符串/字符),因此,cmd.exe(命令行解释器)将以(仅)的方式执行该命令。echo %var%echo

然而echo off,在脚本开始时分配给整个脚本,一旦echo noting |or| echo使用该命令(因为它发生在其变量中而没有分配值/变量来显示),它将显示该echo命令的当前状态,因为没有字符串可显示在屏幕上。

  • 为了测试/调试目的,您可以使用以下方法避免这些消息:
echo. %var%
echo; %var%
echo/ %var%
echo\ %var%
echo= %var%
echo+ %var%
echo( %var%
echo[ %var%
echo: %var%

由于运行时变量中没有值,上述任何echo *命令都会返回一个空白行:


your code... 
echo= %var%
...
  • 返回:
var="apple"

"Text2"
var="orange"

"Text2"
var="pear"

"Text2"
var="lemon"

"Text2"
Press any key to continue . . .

  • 要设置和使用/访问数组索引项,可以使用:

根据分隔符将字符串拆分为子字符串/dostips.com

@echo off

setlocal enabledelayedexpansion
set "_array=apple,orange,pear,lemon"

set "_array_0=%_array:,=" & set /a _i+=1 & set "_array_!_i!=%"
for /l %%i in (0 1 !_i!)do echo:_array_%%~i == "!_array_%%~i!"

%__AppDir__%TimeOut.exe /t 000000010 /nobreak | <con: endlocal
  • 结果:
_array_0 == "apple"
_array_1 == "orange"
_array_2 == "pear"
_array_3 == "lemon"

观察:很好的做法是使用endlocal当它不再需要时。


  • 使用循环设置数组/索引值的一些替代方法:
@echo off && setlocal enabledelayedexpansion

set "_var=apple,orange,pear,lemon" && set/a "_i=100000-100001"
for %%i in (!_var!)do set/a "_i+=1"&&>con set "_var_!_i!=%%~i"
    
for /L %%L in (00,01,0!_i!)do echo\ _var_%%~L == "!_var_%%~L!"
%__AppDir__%TimeOut.exe /t 000000010 /nobreak | <con: endlocal
  • 结果:
 _var_0 == "apple"
 _var_1 == "orange"
 _var_2 == "pear"
 _var_3 == "lemon"

其他资源:

答案2

@echo off

setlocal enabledelayedexpansion

Rem Create variable
set fruit[0]="apple"
set fruit[1]="orange"
set fruit[2]="pear"
set fruit[3]="lemon"


REM x is the last index of the array
set x=3

REM for loop (with 0 for start, 1 for step, x for end)
FOR /L %%a in (0,1,%x%) DO (
   call set var=%%fruit[%%a]%%
   set var
REM   echo %var%
   echo !var!
   call echo "Text2" 
   )
)

endlocal

pause

没有enabledelayedexpansion变量的值在循环开始时始终等于一。var之前为空,因此echo %var%扩展为echo打印当前 ECHO 状态。

enabledelayedexpansion不仅可以使用,%variable%还可以!variable!使用其他方法。第一个方法再次提供循环开始时的值,而第二个方法提供实际值。

为了看到这一切:在命令SET var=zero后立即添加行@echo off并执行初始批处理文件和我的代码(删除REM之前echo %var%

相关内容