Переменные среды в пакетных файлах раскрываются при разборе строки. В случае блоков, разделенных скобками (как if defined
вы их определили ), весь блок считается "строкой" или командой.
Это означает, что все вхождения% FOO% заменяются своими значениями до запуска блока. В вашем случае ни с чем, так как переменная еще не имеет значения.
Для решения этой проблемы вы можете включить отложенное расширение:
setlocal enabledelayedexpansion
Задержка раскрытия вызывает переменные, разделенные восклицательными знаками (!
) оценивать на выполнение вместо анализа, который обеспечит правильное поведение в вашем случае:
if not defined BAR (
set FOO=1
echo Foo: !FOO!
)
help set
детали это тоже:
Наконец, была добавлена поддержка отложенного расширения переменных среды. Эта поддержка всегда отключена по умолчанию, но ее можно включить / отключить с помощью переключателя командной строки /V
к CMD.EXE
. Смотрите CMD /?
Задержка раскрытия переменных среды полезна для преодоления ограничений текущего раскрытия, которое происходит при чтении строки текста, а не при ее выполнении. В следующем примере демонстрируется проблема с немедленным расширением переменной:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
никогда не будет отображать сообщение, так как %VAR%
в обоих операторах IF
заменяется при чтении первого оператора IF, поскольку он логически включает тело IF
, которое является составным оператором. Таким образом, IF внутри составного оператора действительно сравнивает "до" с "после", которое никогда не будет равным. Аналогично, следующий пример не будет работать должным образом:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
в том смысле, что он не будет создавать список файлов в текущем каталоге, а вместо этого просто установит переменную LIST
для последнего найденного файла.
Опять же, это связано с тем, что %LIST%
раскрывается только один раз при чтении оператора FOR
, и в это время переменная LIST
пуста. Итак, фактический цикл FOR, который мы выполняем:
for %i in (*) do set LIST= %i
который просто устанавливает LIST
для последнего найденного файла.
Задержка раскрытия переменных среды позволяет использовать другой символ (восклицательный знак) для раскрытия переменных среды во время выполнения. Если расширение отложенной переменной включено, приведенные выше примеры могут быть написаны следующим образом, чтобы работать как задумано:
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%