17 Stimmen

Batch-Datei-Variablen, die in einer for-Schleife initialisiert werden

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

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

  echo In loop %TMPFILE%
)

echo End loop %TMPFILE%

Wenn ich dies in einer brandneuen Befehlsshell ausführe (ohne definiertes TMPFILE), ist das In-Loop-Echo leer, das End-Loop-Echo jedoch nicht.

Wenn ich ein zweites Mal ausführe, ist der Wert bereits gesetzt und wird ausgegeben, wobei der Satz ignoriert wird, bis die Schleife geschlossen ist.

Haben Sie eine Idee, warum das so ist und wie man es umgehen kann?

21voto

theschmitzer Punkte 11448

Für das Protokoll sieht das korrigierte Skript wie folgt aus:

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 deine Hilfe.

17voto

paxdiablo Punkte 809679

Das liegt daran, dass die Umgebungsvariablen ersetzt werden, wenn der Befehl lesen . Für den folgenden Befehl:

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

den gesamten Befehl (von for bis zur schließenden Klammer) wird gelesen und vor der Ausführung ersetzt.

Sie müssen eine verzögerte Expansion verwenden, z. B. 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 die verzögerte Erweiterung aktivieren, wird die "%" Markierungen funktionieren wie bisher, aber Sie können die "!" Markierungen für die verzögerte Erweiterung.

9voto

laktak Punkte 52075

Das liegt daran, dass der ( )-Block nur einmal geparst wird und %TMPFILE% ersetzt wird, bevor die Schleife ausgeführt wird.

6voto

George V. Reilly Punkte 14862

Sie können auch Folgendes verwenden AUFRUF EINSTELLEN statt einer verzögerten Expansion.

2voto

Garry Offord Punkte 23

Normalerweise rufe ich CMD.EXE mit den Schaltern /e:on und /v:on auf, um Befehlserweiterungen und verzögerte Variablenexpansion zu aktivieren. Dann werden alle Batch-Skripte, die ich verwende, so kodiert, dass sie prüfen, ob die verzögerte Variablenexpansion aktiviert ist.

Dies ist das erste Mal, dass ich höre, dass SETLOCAL Argumente braucht. Ich habe es mit SETLOCAL /? überprüft und siehe da! Das spart mir so viel Zeit und Code.

Ich habe jedoch festgestellt, dass die Befehlserweiterungen in CMD.EXE aktiviert sein müssen, bevor SETLOCAL die Option ENABLEDELAYEDEXPANSION erkennt. Dies geht aus 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.

Ich danke Ihnen beiden für diese wertvolle Antwort.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X