Zmienne środowiskowe w plikach wsadowych są interpretowane podczas parsowania linii. W przypadku bloków ograniczonych nawiasami (jak twój if defined), cały blok liczy się jako “linia” lub polecenie.
To oznacza, że wszystkie wystąpienia %FOO% są zastępowane przez ich wartości przed uruchomieniem bloku. W twoim przypadku z niczym, ponieważ zmienna nie ma jeszcze wartości.
Aby to rozwiązać możesz włączyć delayed expansion:
setlocal enabledelayedexpansion
Delayed expansion powoduje, że zmienne ograniczone wykrzyknikami (!) są analizowane podczas wykonywania zamiast parsowania, co zapewni poprawne zachowanie w twoim przypadku:
if not defined BAR (
set FOO=1
echo Foo: !FOO!
)
help set wyszczególnia to również:
Wreszcie, dodano wsparcie dla opóźnionej interpretacji zmiennych środowiskowych. Obsługa ta jest domyślnie zawsze wyłączona, ale może być włączona/wyłączona za pomocą przełącznika linii komend /V na CMD.EXE. Zobacz CMD /?
Opóźniona interpretacja zmiennych środowiskowych jest przydatna do obejścia ograniczeń obecnej interpretacji, która ma miejsce gdy linia tekstu jest czytana, a nie gdy jest wykonywana. Poniższy przykład demonstruje problem z natychmiastową interpretacją zmiennych:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
nigdy nie wyświetliłoby komunikatu, ponieważ %VAR% w obu instrukcjach IF jest zastępowane, gdy odczytywana jest pierwsza instrukcja IF, ponieważ logicznie zawiera ona ciało IF, które jest instrukcją złożoną. Tak więc IF wewnątrz instrukcji złożonej jest naprawdę porównywaniem “przed” z “po”, które nigdy nie będą równe. Podobnie, następujący przykład nie będzie działał tak, jak oczekiwano:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
w tym, że nie zbuduje listy plików w bieżącym katalogu, ale zamiast tego po prostu ustawi zmienną LIST na ostatni znaleziony plik. Ponownie, dzieje się tak dlatego, że zmienna %LIST% jest interpretowana tylko raz, gdy instrukcja FOR jest odczytywana, a w tym czasie zmienna LIST jest pusta. Tak więc rzeczywista pętla FOR, którą wykonujemy to:
for %i in (*) do set LIST= %i
która po prostu ustawia LIST na ostatni znaleziony plik.
Opóźnione rozwijanie zmiennych środowiskowych pozwala na użycie innego znaku (wykrzyknika) do rozwijania zmiennych środowiskowych w czasie wykonywania. Jeśli opóźnione interpretowanie zmiennych jest włączone, to powyższe przykłady można by zapisać następująco, by działały zgodnie z przeznaczeniem:
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%
```.