2009-03-27 4 views
17

Ich habe eine Batch-Datei, die für Schleife in einer Variablen über SET initialisiert, für eine Reihe von Dateien auf der Festplatte:Batch-Datei Variablen in einem for-Schleife initialisiert

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

    echo In loop %TMPFILE% 
) 

echo End loop %TMPFILE% 

wenn ich laufe dies in einem ganz neuen Befehl Shell (ohne TMPFILE definiert) das In-Loop-Echo ist leer, das End-Loop-Echo jedoch nicht.

Wenn ich ein zweites Mal ausgeführt, ist es bereits festgelegt, und gibt den Wert aus, ignoriert den Satz, bis die Schleife schließt.

Ideen warum ist das, und was ist die Problemumgehung?

Antwort

9

Das ist, weil der() Block nur einmal analysiert wird, ersetzt er% TMPFILE%, bevor es Ihre Schleife ausführt.

+1

Danke, ich sah gerade setlocal ENABLEDELAYED EXPANSION – theschmitzer

21

Für die Aufzeichnung sieht die korrigierte Skript wie folgt:

setlocal ENABLEDELAYEDEXPANSION 

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

    SET TMPFILE=%%F.tmp 

    echo In loop !TMPFILE! 
) 

echo End loop %TMPFILE% 

Danke chris für Ihre Hilfe.

16

Es, weil Umgebungsvariablen ersetzt werden, wenn der Befehl gelesen wird. Für den folgenden Befehl ein:

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

der gesamte Befehl (von for zur schließenden Klammer) gelesen und vor der Ausführung ersetzt.

Sie benötigen eine verzögerte Expansion verwenden, wie zum Beispiel mit:

@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 

Wenn Sie Erweiterung verzögert ermöglichen, die "%" Marker nach wie vor wirken, aber sie die "!" Marker verwenden, um die verzögerte Expansion zu tun.

+2

Ihr Beispiel könnte ein bisschen einfacher sein tho :) – Lajcik

6

Sie können auch CALL SET anstelle der verzögerten Expansion verwenden.

+0

Weise besser lesbar! –

2

Normalerweise rufe ich CMD.EXE mit den Schaltern/e: on und/v: on auf, um Befehlserweiterungen und verzögerte Variablenerweiterungen zu aktivieren. Dann werden alle Batch-Skripts, die ich verwende, codiert, um zu überprüfen, ob die verzögerte Variablenerweiterung aktiviert ist.

Dies ist das erste Mal, dass ich gehört habe, dass SETLOCAL Argumente annimmt. Ich habe mit SETLOCAL /? und sicher genug! Das ist so eine Zeit und ein Sicherheitsfaktor für mich.

Ich habe jedoch festgestellt, dass Befehlserweiterungen in CMD.EXE aktiviert werden müssen, bevor SETLOCAL die Option ENABLEDELAYEDEXPANSION erkennt. Dies ist von der Ausgabe von 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. 

Vielen Dank für diese wertvolle Antwort.