DOS: переменная SET и ECHO внутри (...) блока

У меня возникла проблема с set не работающим в пакетном файле; потребовалось некоторое время, чтобы решить проблему; сначала я думал, что это связано с вызовами подпрограмм...

script

@echo off
setlocal
set a=aaa
echo a = "%a%"
(
set b=bbb
echo b = "%b%"
)

выводит вывод

a = "aaa"
b = ""

тогда как я ожидал бы

a = "aaa"
b = "bbb"

Почему это, пожалуйста? Это ошибка в DOS? Возможно, что-то о синтаксисе группировки команд (...), о котором я не знаю.

Спасибо.

Ответ 1

Пользователь с задержкой расширения и! вместо%

@echo off
setlocal enableextensions enabledelayedexpansion
set a=aaa
echo a = "%a%"
(
set b=bbb
echo b = "!b!"
)

Ответ 2

Что происходит, так это то, что пакетный интерпретатор рассматривает все между скобками одну строку. Это означает, что он выполняет замену переменных на все, что находится между скобками, прежде чем запускать любую из команд.

Итак:

(
set b=bbb
echo b = "%b%"
)

становится:

(
set b=bbb
echo b = ""
)

Переменная b устанавливается, но, очевидно, она не установлена ​​перед запуском команды SET.

Ответ 3

Вам нужно замедленное расширение, или пакетный интерпретатор будет интерполировать все переменные во время разбора вместо времени выполнения.

setlocal enableextensions enabledelayedexpansion

См. этот вопрос для примера и некоторое объяснение.