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%
```.