2009-03-27 29 views
17

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

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

    echo In loop %TMPFILE% 
) 

echo End loop %TMPFILE% 

cuando corro esto en un nuevo comando shell (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 ¿por qué esto es y cuál es la solución?

Respuesta

9

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

+1

Gracias, acabo de ver setlocal ENABLEDELAYED EXPANSION – theschmitzer

21

Para el registro, el guión corregido se parece a esto:

setlocal ENABLEDELAYEDEXPANSION 

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

    SET TMPFILE=%%F.tmp 

    echo In loop !TMPFILE! 
) 

echo End loop %TMPFILE% 

Gracias a Chris por su ayuda.

16

Esto porque las variables de entorno se sustituyen cuando el comando es , lea. Para el comando siguiente:

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

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

Es necesario utilizar la expansión retardada, por ejemplo 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 

Al habilitar retrasa la expansión, los marcadores "%" siguen actuando como antes pero se pueden utilizar los marcadores "!" para hacer la expansión retardada.

+2

Su ejemplo podría haber sido un poco más simple si :) – Lajcik

6

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

+0

¡De manera más legible! –

2

Normalmente, invoca 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, 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.

Cuestiones relacionadas