Я думаю, вы должны понимать, что такое задержанное расширение . Существующие ответы не объясняют это (достаточно) ИМХО.
Ввод SET /?
достаточно хорошо объясняет:
Задержка расширения переменной среды полезна для обхода
ограничения текущего расширения, которое происходит, когда линия
текст читается, а не когда он выполняется. Следующий пример
демонстрирует проблему с немедленным расширением переменной:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
никогда не будет отображать сообщение, так как% VAR% в операторах ОБА 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%
Другим примером является этот командный файл:
@echo off
setlocal enabledelayedexpansion
set b=z1
for %%a in (x1 y1) do (
set b=%%a
echo !b:1=2!
)
Это печатает x2
и y2
: каждый 1 заменяется на 2.
Без setlocal enabledelayedexpansion
восклицательные знаки - только это, поэтому он будет повторять !b:1=2!
дважды.
Поскольку нормальные переменные среды раскрываются, когда оператор (block) равен read , при расширении %b:1=2%
используется значение, b
перед циклом: z2
(но y2
, если не задано ).