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

the*_*zer 17 windows batch-file

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

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

  echo In loop %TMPFILE%
)

echo End loop %TMPFILE%
Run Code Online (Sandbox Code Playgroud)

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

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

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

the*_*zer 21

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

setlocal ENABLEDELAYEDEXPANSION

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

  SET TMPFILE=%%F.tmp

  echo In loop !TMPFILE!
)

echo End loop %TMPFILE%
Run Code Online (Sandbox Code Playgroud)

谢谢克里斯的帮助.


pax*_*blo 16

这是因为在读取命令时会替换环境变量.对于以下命令:

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

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
Run Code Online (Sandbox Code Playgroud)

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


lak*_*tak 9

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


Geo*_*lly 6

您也可以使用CALL SET而不是延迟扩展.