如何在循环内修改环境变量值? [英] How to modify environment variable value inside a loop?

查看:48
本文介绍了如何在循环内修改环境变量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在批处理文件中有以下代码:

I have following code in a batch file:

set "start=2"

FOR /L %%a in (1,1,3) DO (
    FOR /L %%b in (%start%,1,3) DO (
        echo %start% Before Call
        call :changestring
        FOR /L %%c in (1,1,3) DO (
            REM Nothing
        )
    )
)

pause
Goto :Eof

:changestring
echo %start% Before Set
set "start=1"
echo %start% After Set
pause
goto :eof

我想要的是第二个 FOR 循环中两次引用了变量 start 的值,其中%start% 2 <使用命令行 call:changestring 运行子例程 changestring 后,将/code>更改为 1 .

What I want is that value of variable start referenced twice in second FOR loop with %start% changes from 2 to 1 after running subroutine changestring with the command line call :changestring.

环境变量 start 的值在子例程中由两个 echo 的输出从 2 修改为 1 .代码>子例程中的命令行.但是在第二个 FOR 循环中,该值始终为 2 并且不会更改.

The value of the environment variable start is modified in subroutine from 2 to 1 as output by the two echo command lines in subroutine. But in the second FOR loop the value is always 2 and does not change.

如何在第二个 FOR 循环中修改环境变量 start 的值?

How to modify value of environment variable start on second FOR loop?

推荐答案

在不考虑<代码> @echo off (通常在批处理文件顶部使用)来调试此批处理文件:

Following is output up to first execution of pause on running the batch file as posted in question from within a command prompt window without @echo off as usually used at top of a batch file to debug this batch file:

set "start=2"

FOR /L %a in (1 1 3) DO (FOR /L %b in (2 1 3) DO (
echo 2 Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
) )

(FOR /L %b in (2 1 3) DO (
echo 2 Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
) )

(
echo 2 Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
)
2 Before Call

echo 2 Before Set
2 Before Set

set "start=1"

echo 1 After Set
1 After Set

pause

Windows命令解释为 cmd.exe 解释,并在不执行 echo off 的情况下始终执行命令行来执行命令行输出按照中所述进行预处理/解析后,Windows命令解释器(CMD.EXE)如何解析脚本?

Windows command interpreted cmd.exe interpreting the batch file and executing the command lines outputs with no echo off always the command line before execution after preprocessing/parsing it as described at How does the Windows Command Interpreter (CMD.EXE) parse scripts?

可以看出,以()开头并以匹配的)结尾的命令块在执行最外部的 FOR 命令.在对整个命令块进行预处理期间,已用引用的环境变量的当前值 2 替换了两次出现的%start%.因此, FOR 接下来要使用的整个命令块不再包含环境变量引用.只有循环变量引用保留在命令块中.

It can be seen that the command block starting with ( and ending with matching ) is completely preprocessed by Windows command interpreter before executing the most outer FOR command the first time. Both occurrences of %start% have been replaced during preprocessing the entire command block by the current value 2 of referenced environment variable. So the entire command block used next several times by FOR does not contain anymore an environment variable reference. Only the loop variable references remain in command block.

在命令提示符窗口中运行 set/?时输出的命令 SET 的帮助描述了使用%variable%在预处理过程中已被评估. SET 的帮助还描述了 IF 条件和 FOR 循环的解决方案,该循环在命令中更改了环境变量的当前值阻止或循环执行期间:延迟扩展的使用.

The help of command SET output on running set /? in a command prompt window describes this problematic of all environment variable references done with %variable% being evaluated already during preprocessing. And help of SET describes also what is the solution for an IF condition and a FOR loop on which current value of environment variable changes within the command block or during loop execution: the usage of delayed expansion.

因此,请按照此答案中的说明使用命令 SETLOCAL ENDLOCAL 除了默认启用且此处也需要的命令扩展之外,还可以启用延迟的环境变量扩展.

So let's use the commands SETLOCAL and ENDLOCAL as explained in this answer to enable also delayed environment variable expansion in addition to command extensions which are enabled by default and needed here too.

setlocal EnableExtensions EnableDelayedExpansion
set "start=2"

FOR /L %%a in (1,1,3) DO (
    FOR /L %%b in (!start!,1,3) DO (
        echo !start! Before Call
        call :changestring
        FOR /L %%c in (1,1,3) DO (
            REM Nothing
        )
    )
)

endlocal
pause
goto :EOF

:changestring
echo %start% Before Set
set "start=1"
echo %start% After Set
pause
goto :EOF

环境变量 start 现在在第二个 FOR 命令行及其命令块中用!start!引用了两次,这意味着延迟扩展在已修改的批处理文件的第一行中启用.

The environment variable start is referenced now twice with !start! in second FOR command line and its command block which means with delayed expansion as being enabled in first line of modified batch file.

在运行此修改的批处理文件之前,Windows命令解释器的输出直到第一个 pause 都为:

The output by Windows command interpreter up to first pause on running this modified batch file is now:

setlocal EnableExtensions EnableDelayedExpansion

set "start=2"

FOR /L %a in (1 1 3) DO (FOR /L %b in (!start! 1 3) DO (
echo !start! Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
) )

(FOR /L %b in (!start! 1 3) DO (
echo !start! Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
) )

(
echo !start! Before Call
 call :changestring
 FOR /L %c in (1 1 3) DO (REM Nothing )
)
2 Before Call

echo 2 Before Set
2 Before Set

set "start=1"

echo 1 After Set
1 After Set

pause

!start!都保留在命令块中,未经预处理.因此,它实际上实际上始终引用在循环执行期间被修改的环境变量 start 的当前值.

Both !start! remain in command block unmodified after preprocessing. So it really references now always the current value of environment variable start being modified during execution of the loops.

在子例程中无需将%start%替换为!start!,因为这两个 echo 命令行不在命令块之内,因此在立即执行命令 ECHO 之前,将每个命令行进行预处理,方法是用环境变量的当前值替换%start%.

There is no need to replace %start% in the subroutine by !start! as it can be seen because both echo command lines are not within a command block and so each command line is preprocessed with replacing %start% by current value of environment variable just before immediately executing the command ECHO.

我希望在预处理/解析单个命令行或整个命令块期间,环境变量的立即扩展和延迟扩展之间的区别现在已经清楚.

I hope the difference between immediate and delayed expansion of environment variables during preprocessing/parsing a single command line or an entire command block is clear now.

顺便说一句:变量的名称 start 不好. start 可以用作环境变量名称,但是还有命令 START 可以在同一批处理文件中使用,这使得区分环境变量更加困难start 和命令 start .最好将其作为变量名,例如 FirstNumber .

By the way: The name start for the variable is not good. start can be used as environment variable name, but there is also the command START which could be used in same batch file making it more difficult to distinguish between environment variable start and command start. Better would be as variable name for example FirstNumber.

使用 FirstNumber 而不是 start 的优化代码,并且使用算术表达式将该数字递减,从而可以在不使用的情况下引用环境变量,但是在评估算术表达式时仍使用环境变量的当前值.以 2 开头的第一个数字永远不应减小到小于1的值,这是二进制的原因,或者以 1 代替.

An optimized code on which FirstNumber is used instead of start and on which the number is decremented using an arithmetic expression making it possible to reference an environment variable without usage of % or ! and nevertheless using current value of environment variable during evaluation of the arithmetic expression. The first number starting with 2 should be never decremented to a value lower than 1 being the reason for binary OR it with 1.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "FirstNumber=2"

FOR /L %%a in (1,1,3) DO (
    FOR /L %%b in (!FirstNumber!,1,3) DO (
        echo !FirstNumber! before decrement
        set /A "FirstNumber=FirstNumber - 1 | 1"
        FOR /L %%c in (1,1,3) DO REM Nothing
    )
)

endlocal

运行此批处理文件时,顶部 @echo关闭的输出为:

The output on running this batch file with @echo off at top is:

2 before decrement
1 before decrement
1 before decrement
1 before decrement
1 before decrement
1 before decrement
1 before decrement
1 before decrement

当然, set/A"FirstNumber = FirstNumber-1 | 1" 在这里可以仅仅是对环境变量赋值的标准字符串,即 set"FirstNumber = 1" .但是我想证明,在算术表达式中可以仅通过环境变量的名称来引用环境变量,以便在对表达式求值时利用环境变量的当前值.还可通过命令 SET 来描述此行为.

Of course set /A "FirstNumber=FirstNumber - 1 | 1" could be here simply a standard string to environment variable assignment, i.e. set "FirstNumber=1". But I wanted to demonstrated that environment variables can be referenced by just their names within an arithmetic expression to make use of current values of the environment variables during evaluation of the expression. This behavior is also described by help of command SET.

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • 呼叫/?
  • echo/?
  • endlocal/?
  • 用于/?
  • 转到/?
  • 暂停/?
  • rem/?
  • 设置/?
  • setlocal/?
  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

结论:认真阅读要使用的命令,应用程序或函数的帮助或文档,对于程序员或脚本编写者而言,避免在编写代码时遇到问题始终是一种好习惯.

Conclusion: Reading carefully the help or documentation of a command, application, or function to use is always good practice for a programmer or script writer to avoid problems on writing coding.

这篇关于如何在循环内修改环境变量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆