Frage

Ich schreibe eine einfache .bat-Datei, und ich habe in einige seltsame Verhalten führen. Es gibt ein paar Orte, wo ich eine einfache if / anderes zu tun haben, aber der Code innerhalb der Blöcke scheinen nicht richtig zu funktionieren.

Hier ist ein einfacher Fall, der den Fehler zeigt:

@echo off

set MODE=FOOBAR

if "%~1"=="" (
  set MODE=all
  echo mode: %MODE%
) else (
  set MODE=%~1
  echo mode: %MODE%
)
echo mode: %MODE%

Der Ausgang Ich erhalte ist:

C:\>test.bat test
mode: FOOBAR
mode: test

Warum ist das Echo in dem Codeblock den neuen Wert der Variablen nicht bekommen? In dem eigentlichen Code Ich schreibe ich brauche ein paar Variablen erstellen und sie in dem Rahmen der if / else verweisen. Ich konnte schalten diese Etiketten zu verwenden und gotos anstelle eines if / else, aber das scheint nicht annähernd so sauber.

Was sind die Ursachen dieses Verhalten? Gibt es irgendeine Art von Limit auf Variablen innerhalb Codeblöcke?

War es hilfreich?

Lösung

Sie führen in das Problem der statischen Variablen Expansion cmd. Die Variable MODE wird nur einmal ausgewertet. Sie können das sehen, wenn Sie das @ echo off line weglassen.

Aus der Menge /? Dokumentation:

  

Schließlich Unterstützung für die verzögerte Erweiterung von Umgebungsvariablen hat   hinzugefügt. Diese Unterstützung ist immer   standardmäßig deaktiviert, kann aber sein,   aktiviert / über den / V-Befehl Behinderte   Leitungsschalter nach CMD.EXE. Siehe CMD /?

     

Verzögerte Erweiterung von Umgebungsvariablen ist nützlich für die Fortbewegung   die Grenzen des aktuellen   Expansion, die der, wenn eine Linie passiert,   Text gelesen wird, nicht, wenn es ausgeführt wird.   Das folgende Beispiel zeigt die   Problem mit sofortigem Variable   Expansion:

 set VAR=before
 if "%VAR%" == "before" (
     set VAR=after
     if "%VAR%" == "after" @echo If you see this, it worked
 )
     

würde nie die Nachricht anzuzeigen, da   das% VAR% in IF-Anweisungen BEIDE ist   wenn der erste substituierte IF   Anweisung gelesen wird, da es logisch   weist der Körper des IF, das ist   eine zusammengesetzte Anweisung. So ist die IF   innerhalb der zusammengesetzten Anweisung ist   wirklich zu vergleichen „vor“ mit „nach“   die nie gleich sein. Ähnlich,   Im folgenden Beispiel wird nicht funktionieren wie   erwartet:

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
     

, dass es baut keine Liste   Dateien im aktuellen Verzeichnis, aber   stattdessen setzen nur die LIST   Variable in die letzte Datei gefunden.   Auch dies ist, weil die% LIST% ist   erweitert nur einmal, wenn die FOR   Anweisung gelesen wird, und zu diesem Zeitpunkt   die LIST Variable ist leer. so ist die   Ist FOR-Schleife ist, die wir ausführen:

for %i in (*) do set LIST= %i
     

, die nur Liste Einstellung auf das hält   letzte Datei gefunden.

     

Verzögerte Erweiterung von Umgebungsvariablen   Damit können Sie ein anderes verwenden,   Zeichen (das Ausrufezeichen) an   erweitern Umgebungsvariablen an   Ausführungszeit. Wenn verzögerte Variable   Expansion ermöglicht wird, die oberhalb   Beispiele geschrieben werden könnte wie folgt   zu arbeiten, wie beabsichtigt:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%

Andere Tipps

setlocal EnableDelayedExpansion

den / v-Freigabe-Flag

Sieht aus wie die Lese- und Schreib verschiedene Scoping-Regeln verwenden.

Wenn Sie beseitigen diese Zeile

set MODE=FOOBAR

es wird erwartet funktionieren. So müssen Sie wahrscheinlich eine komplexe Reihe haben, wenn if / elses die Variablen bevölkert werden, wie Sie möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top