在for循环中初始化的批处理文件变量

时间:2009-03-27 18:52:11

标签: windows batch-file

我有一个批处理文件,它通过for循环中的SET初始化变量,对于磁盘上的一组文件:

for %%f in (%MYTARGETDIR%\*config.xml) do (
  SET TMPFILE=%%F.tmp

  echo In loop %TMPFILE%
)

echo End loop %TMPFILE%

当我在一个全新的命令shell(没有定义TMPFILE)中运行它时,In循环回显为空,但结束循环回显不是。

当我第二次运行时,它已经设置并输出其值,忽略该设置直到循环关闭。

为什么会这样,以及解决方法是什么?

5 个答案:

答案 0 :(得分:21)

对于记录,更正后的脚本如下所示:

setlocal ENABLEDELAYEDEXPANSION

for %%f in (%MYTARGETDIR%\*config.xml) do (

  SET TMPFILE=%%F.tmp

  echo In loop !TMPFILE!
)

echo End loop %TMPFILE%

感谢克里斯的帮助。

答案 1 :(得分:16)

因为当命令 read 时,环境变量被替换。对于以下命令:

for %%f in (%mytargetdir%\*config.xml) do (
    set tmpfile=%%f.tmp
    echo In loop %tmpfile%
)

在执行之前读取并替换整个命令(从for到右括号)。

您需要使用延迟扩展,例如:

@echo off
    setlocal enableextensions enabledelayedexpansion
    set full=/u01/users/pax
:loop1
    if not "!full:~-1!" == "/" (
        set full2=!full:~-1!!full2!
        set full=!full:~,-1!
        goto :loop1
    )
    echo !full!
    endlocal

启用延迟展开后,"%"标记仍然可以像以前一样运行,但您可以使用"!"标记执行延迟扩展。

答案 2 :(得分:9)

那是因为()块只被解析一次,它在运行循环之前替换了%TMPFILE%。

答案 3 :(得分:6)

您也可以使用CALL SET代替延迟扩展。

答案 4 :(得分:2)

通常,我使用/ e:on和/ v:on开关调用CMD.EXE以启用命令扩展和延迟变量扩展。然后编码我使用的任何批处理脚本以检查延迟变量扩展是否已打开。

这是我第一次听说SETLOCAL接受争论。我用SETLOCAL /检查了?果然!对我来说,这是一个时间和代码保护程序。

但是,我注意到在SETLOCAL识别ENABLEDELAYEDEXPANSION选项之前,必须在CMD.EXE中启用命令扩展。这是来自SETLOCAL /?

的输出
If Command Extensions are enabled SETLOCAL changes as follows:

SETLOCAL batch command now accepts optional arguments:
        ENABLEEXTENSIONS / DISABLEEXTENSIONS
            enable or disable command processor extensions. These
            arguments takes precedence over the CMD /E:ON or /E:OFF
            switches. See CMD /? for details.
        ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION
            enable or disable delayed environment variable
            expansion. These arguments takes precedence over the CMD
            /V:ON or /V:OFF switches. See CMD /? for details.

谢谢你们这个有价值的答案。