Las variables de archivo de proceso por lotes inicializadas en un bucle for

Tengo un archivo por lotes que inicializa las variables a través de SET dentro de un ciclo for, para un conjunto de archivos en el disco:

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

cuando ejecuto esto en un nuevo shell de comandos (sin TMPFILE definido), el eco de bucle In está vacío, pero el eco del bucle final no.

Cuando corro por segunda vez, ya está configurado, y muestra su valor, ignorando el conjunto hasta que se cierra el ciclo.

Ideas de por qué es esto, y cuál es la solución?

Eso es porque el bloque () se analiza solo una vez, sustituye% TMPFILE% antes de que ejecute el ciclo.

Para el registro, el script corregido se ve así:

 setlocal ENABLEDELAYEDEXPANSION for %%f in (%MYTARGETDIR%\*config.xml) do ( SET TMPFILE=%%F.tmp echo In loop !TMPFILE! ) echo End loop %TMPFILE% 

Gracias Chris por tu ayuda.

Es porque las variables de entorno se sustituyen cuando se lee el comando. Para el siguiente comando:

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

todo el comando (desde for hasta el paréntesis de cierre) se lee y se sustituye antes de la ejecución.

Necesita usar expansión retrasada, como con:

 @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 

Cuando habilita la expansión retrasada, los marcadores "%" todavía funcionan como antes, pero puede usar el "!" marcadores para hacer la expansión retrasada.

También puede usar CALL SET en lugar de expansión retrasada.

Normalmente, invoco CMD.EXE con los modificadores / e: on y / v: on para habilitar las extensiones de comando y la expansión de variable retrasada. Luego, todos los scripts por lotes que utilizo están codificados para verificar que la expansión de la variable retrasada esté activada.

Esta es la primera vez que escucho que SETLOCAL toma argumentos. Lo revisé con SETLOCAL /? ¡y por supuesto! Este es un ahorro de tiempo y código para mí.

Sin embargo, sí noté que las extensiones de comando deben estar habilitadas en CMD.EXE antes de que SETLOCAL reconozca la opción ENABLEDELAYEDEXPANSION. Esto es de la salida de 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. 

Gracias a ambos por esta valiosa respuesta.